java – 面向对象的设计 – 何时使用getClass和instanceof
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 面向对象的设计 – 何时使用getClass和instanceof,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3032字,纯文字阅读大概需要5分钟。
内容图文
![java – 面向对象的设计 – 何时使用getClass和instanceof](/upload/InfoBanner/zyjiaocheng/805/8ab77e2c602043808caa010288352d6e.jpg)
在大学演讲期间,讲师说使用getClass和instanceof表示设计不好.
什么是不良设计的示例用法?使用这些方法可能导致什么问题?这些方法是否有任何有效的用法,这些设计都不错?
解决方法:
糟糕的用法
我想说这是大多数情况下设计糟糕的表现.例如,假设您有一个对象列表,您正在执行instanceof,然后执行强制转换,然后调用特定于该类的方法.相反,这些对象应该有共同的超类,并且应该在那里声明方法 – 然后根据对象的实际类型执行不同的代码(因为子类可以定义不同的实现).
private static class A {
private void printA() {
System.out.println("A");
}
}
private static class B {
private void printB() {
System.out.println("B");
}
}
public static void main(String[] args) {
List<Object> list = asList(new A(), new B(), new A());
list.forEach(element -> { // this is bad, don't do it!
if (element instanceof A) {
((A) element).printA();
}
if (element instanceof B) {
((B) element).printB();
}
});
}
相反,你应该这样做:
private interface Printer {
void print();
}
private static class A implements Printer {
@Override
public void print() {
System.out.println("A");
}
}
private static class B implements Printer {
@Override
public void print() {
System.out.println("B");
}
}
public static void main(String[] args) {
List<Printer> list = asList(new A(), new B(), new A());
list.forEach(Printer::print);
}
好的用法
等于方法
您将在自动生成的equals方法中看到的有效用例.在实际比较对象之前,检查它们是否属于同一类.如果不是,则它们不能相等,因此存在快速失败的优化.这实际上是由采用Object类型参数的equals方法强制执行的.即使我们比较的两个对象实际上是相等的,我们也必须转换参数,在这之前我们应该检查它的类,以便返回false而不是获得ClassCastException.
IntelliJ生成的Equals方法:
public class Person {
private String name;
private String surname;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (!name.equals(person.name)) return false;
return surname.equals(person.surname);
}
}
使用反射API的工具
使用这些方法的另一个有效案例是,例如在创建各种工具(如POJO到json映射器)时,只能通过反射API来完成.
编辑:
在评论中提出问题之后,以下是如何实施动物列表的工作示例,其中狗可以跑,鹰可以跑和飞:
public static abstract class Animal {
protected final String name;
public Animal(String name) {
this.name = name;
}
public void run() {
System.out.println(name + " runs");
}
public abstract void move();
}
public static class Dog extends Animal {
public Dog() {
super("Dog");
}
@Override
public void move() {
run();
}
}
public static class Eagle extends Animal {
public Eagle() {
super("Eagle");
}
public void fly() {
System.out.println(name + " flies");
}
@Override
public void move() {
fly();
}
}
public static void main(String[] args) {
List<Animal> animals = Arrays.asList(new Dog(), new Eagle());
animals.forEach(Animal::move);
System.out.println("Eagle can run too!");
new Eagle().run();
}
输出:
Dog runs
Eagle flies
Eagle can run too!
Eagle runs
它是关于分析代码的使用方式和提取公共部分的全部内容.如果在循环中你总是命令动物运行,那么因为在Animal上声明了run(),所以不需要强制转换.另一方面,我们希望动物移动,无论如何,所以让他们通过在Animal类中创建抽象的move()方法来选择它们的默认移动类型.
内容总结
以上是互联网集市为您收集整理的java – 面向对象的设计 – 何时使用getClass和instanceof全部内容,希望文章能够帮你解决java – 面向对象的设计 – 何时使用getClass和instanceof所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。