Java 使用.getClass()是否被视为糟糕的设计?
我目前正在实现一个函数,使用超类作为参数 例如:Java 使用.getClass()是否被视为糟糕的设计?,java,oop,Java,Oop,我目前正在实现一个函数,使用超类作为参数 例如: private void foo(Parent parent) { if(parent.getClass() == Child1.class) { Child1 c1 = (Child1) parent; System.out.println(c1.getChild1Attribute()); } else if(parent.getClass() == Child2.class) {
private void foo(Parent parent) {
if(parent.getClass() == Child1.class) {
Child1 c1 = (Child1) parent;
System.out.println(c1.getChild1Attribute());
}
else if(parent.getClass() == Child2.class) {
Child2 c2 = (Child2) parent;
System.out.println(c1.getChild2Attribute());
}
else if(parent.getClass() == Parent.class) {
System.out.println(parent.getParentAttribute());
}
}
这是个坏主意吗
我在这里读到一些帖子说,使用getClass()
或instanceof
是糟糕的设计:
- 是的,这是一个糟糕的设计
相反,您应该在超类中创建一个抽象方法,并在每个子类中重写它以执行所需的操作。这不一定是一个糟糕的设计,但它表明可能正在发生错误 您的具体情况看起来很糟糕,因为一个方法似乎知道多个类。这可能表明您缺少过载的可能性,或者您没有机会使用多种调度模式之一:
// Three overloads - one per target class
private void foo(Parent obj) {
}
private void foo(Child1 obj) {
}
private void foo(Child2 obj) {
}
常见的多分派模式之一是,查看它是否适用于您正在解决的问题。首选
实例的方法
我支持instanceof方法的原因是,当您使用getClass方法时,您有一个限制,即对象仅等于同一类、同一运行时类型的其他对象
是的,这是不良设计的标志。这就增加了在单个类中处理不同类的复杂性,而不是将相关知识封装在适当的类中。当您向层次结构中添加更多的类时,这会造成伤害,因为编译器不会提醒您为
foo
实现相关的新功能
更好的版本是
private void foo(Parent parent){
System.out.println(parent.getFooParentAttribute());
}
然后在每个类上实现
getFooParentAttribute
。您的方法存在两个问题。首先,假设您添加了一个子类Parent
,Child3
。你的任何箱子都不包括这个,所以它根本不打印任何东西。如果您添加了一个新的子类Child1
,ChildOfChild1
,情况也是如此。这也不包括在内
如果改用instanceof
,则ChildOfChild1
将显示为Child1
的实例,Child3
将显示为Parent
的实例
但是一般来说,你想要完全避免这种模式的原因是,所有这些情况都是令人惊讶的。通常更好的方法是写作
void foo(Parent p) {...}
然后把一般代码放进去,然后对于任何特殊情况,创建一个
void foo(Child1 c) {...}
这让事情变得更清楚了:如果你看到这两种方法,你就会知道
Child1
(及其子类)有一些特殊的大小写代码,而Parent
和任何其他子类的处理方式都是一样的。如果你有更好的选择,那就是糟糕的设计。但有时你不会。如果可能,使用本机Java方法dispatch,而不是If instanceof
惯用语。是的,一般来说,这是糟糕的OO设计。这不一定不好,但你为什么要这样做?这只是语法上的甜点;基本设计是相同的,关于foo
如何响应各种参数类的知识仍然存在于单个类中。它还需要重复调用System.out.println
。@larsmans知道如何响应各种参数类并不是一个坏的设计,只要您知道您涵盖了所有参数类。任何实现visitor的人都知道:):):)即使如此,instanceof
也表明设计糟糕。(我知道你需要它来做equals(Object)
)@TomHawtin-tackline谢谢你纠正我的错误。我可以知道怎么做吗??