我有两个类 A 和 B,其中 B 是 A 的子类,A 不是抽象的。因此,我可以拥有作为 A 实例的对象和作为 B 实例的对象(因此也是 A 的实例)。
如何区分仅是 A 实例的对象?
当然,我可以编写类似“object instaceof A && !(object instance of B)”之类的东西,但这是一个非常糟糕的设计,因为每次向 A 添加新的子类时我都需要更改代码。更好的选择?
我有两个类 A 和 B,其中 B 是 A 的子类,A 不是抽象的。因此,我可以拥有作为 A 实例的对象和作为 B 实例的对象(因此也是 A 的实例)。
如何区分仅是 A 实例的对象?
当然,我可以编写类似“object instaceof A && !(object instance of B)”之类的东西,但这是一个非常糟糕的设计,因为每次向 A 添加新的子类时我都需要更改代码。更好的选择?
object.getClass() == A.class
为什么要他们区分?通常这与 OO 相反。你有不同的实例,你不需要区分,因为不同的实现做的一切都是正确的。
如果您需要这样做,那么应该有一个协议。为此目的,有一个方法可以返回要识别的东西。这也更灵活。
如果没有充分理由使用它,我会 instanceOf 和 getClass 已经考虑不好的风格
这不是表明 B 不是真正的 A 吗?我不完全确定你应该进入这种情况吗?也许你可以改进你的设计?
更好的方法是使测试成为方法的结果
class A {
public boolean isSomeTest() {
return true;
}
}
class B extends A {
public boolean isSomeTest() {
return false;
}
}
然后,如果您添加一个扩展 A 的 C,您可以允许它返回 true 或 false。
isSomeTest 的名称应该清楚地表明返回 true 或 false 的含义。
这就是我认为你在说的:
public class A {
}
public class B extends A {
}
稍后在代码中:
A apple = new A();
B banana = new B();
以下是一些您可能会觉得有用的选项:
if (apple.getClass() == A.class) { // Found an A }
if (banana.getClass() == A.class) { // This is not an A, won't get here. }
if (apple instanceof A) { // This is definitely an A }
if ((apple instanceof A) && (!(apple instanceof B))) { // It's an A but not a B }
关于最后一个选项,您编写以下内容:
当然,我可以编写类似“object instaceof A && !(object instance of B)”之类的东西,但这是一个非常糟糕的设计,因为每次向 A 添加新的子类时我都需要更改代码。更好的选择?
多态性几乎总是在这里帮助我们。您关于每次添加子类时更改代码的观点正是您应该认识到的标准面向对象设计演变的症状。想想你试图产生的行为。您能否将其推入课程本身,而不是将其委托给外部提供者,以推断其当前正在处理的课程?
如果没有更多信息,我无法提供太多指导,但这里有一个相当简单的示例:
// Instead of this
if (apple.isClassA()) { // run class A code
} else if (apple.isClassB()) { // run class B code
// And so forth
}
修改设计,使其更像这样:
public class A {
public void executeCommand() {
// run class A code
// This method knows that it's definitely an A, not a B
}
}
public class B extends A {
public void executeCommand() {
// run class B code
// This method knows that it's a B (and, therefore, an A as well).
}
}
稍后在执行代码中,您将之前的 if 测试替换为:
apple.executeCommand();
banana.executeCommand();
诚然,这是一个几乎微不足道的面向对象设计审查,但它可能会动摇一些东西并帮助您解决子类化问题。