Java对象的最特定子类?

Java对象的最特定子类?,java,inheritance,instanceof,Java,Inheritance,Instanceof,我有两个类A和B,其中B是A的子类,A不是抽象的。因此,我可以拥有作为A实例的对象和作为B实例(因此也是A实例)的对象 如何区分仅为实例的对象 当然,我可以编写类似“对象instaceof A&&!(B的对象实例)”的东西,但这是一个非常糟糕的设计,因为每次向A添加新的子类时,我都需要更改代码。更好的替代方案?这难道不表明B实际上不是A吗? object.getClass() == A.class 我不完全确定你是否应该卷入这种情况?也许你可以改进你的设计???为什么你想让它们与众不同?通常这

我有两个类A和B,其中B是A的子类,A不是抽象的。因此,我可以拥有作为A实例的对象和作为B实例(因此也是A实例)的对象

如何区分仅为实例的对象


当然,我可以编写类似“对象instaceof A&&!(B的对象实例)”的东西,但这是一个非常糟糕的设计,因为每次向A添加新的子类时,我都需要更改代码。更好的替代方案?

这难道不表明B实际上不是A吗?
object.getClass() == A.class

我不完全确定你是否应该卷入这种情况?也许你可以改进你的设计???

为什么你想让它们与众不同?通常这与OO相反。您不需要区分不同的实例,因为不同的实现可以做所有正确的事情

如果您需要这样做,那么应该有一个协议。有一个方法可以返回要识别的内容。这也更加灵活


我想,如果没用的话,GET类已经考虑了坏的风格。

< P>一个更好的方法是使测试成为方法

的结果。
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 }
关于最后一个选项,请编写以下内容:

当然,我可以写这样的东西 “A&&!(对象)的对象安装 例如B)“但这是一个非常复杂的问题 糟糕的设计,因为我需要改变 每次我添加新的 A的子类。更好的选择

object.getClass() == A.class
多态性几乎总是帮助我们。您关于每次添加子类时更改代码的观点正是您应该认识到的标准面向对象设计演化的症状。想想你试图做出的行为。你能把它推到类本身中,而不是委托给外部提供者,由外部提供者来推断它当前在处理什么类吗

如果没有更多的信息,我无法给出太多的指导,但这里有一个相当简单的例子:

// 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();

诚然,这是一个几乎微不足道的面向对象设计审查,但它可能会动摇某些东西,并帮助您解决子类化问题。

为什么香蕉会将苹果子类化?是的,诚然,这是一个有趣的想法。也许我正试图通过基因工程在树上制造不同种类的儿童果汁盒。我试图避免“A级”和“A级theA”或“Aaa”这两个“标准”可怕的组合;相反,A代表苹果,B代表香蕉。如果你能想到以B开头的各种苹果,我会改变它。用你的答案+1。java是一种静态语言,如果你必须考虑对象的动态类型,请访问访问者模式。这看起来像调度器模式的情况下要以非常好的方式来解决。该模式支持依赖于项目类型的不同行为,但我不确定它在Java中是否可行。IMHO语言需要更好地支持元编程。。。