从概念上理解继承,接口和多态,我创建了几个类来测试东西。我得到的结果不是我预期的结果。代码如下:
public class Animal implements Comparable{
//Animal constructor & methods
public int compareTo(Object arg0){System.out.println("Animal.compareTo");}
}
public class Bear extends Animal{
//Bear constructor & methods
}
public class PolarBear extends Bear implements Comparable{
//PolarBear constructor & methods
public int compareTo(Object arg0) {System.out.println("PolarBear.compareTo");
我没有得到任何错误,说我无法再次实现Comparable。但是在我的测试中,一旦我创建了PolarBear,我就无法回到Animal的compareTo方法,即使PolarBear应该继承Animal的compareTo。我测试了以下内容:
Animal bobo = new PolarBear();
bobo.compareTo(null);
((PolarBear) bobo).compareTo(null);
((Animal)bobo).compareTo(null);
((Comparable) bobo).compareTo(null);
他们每个人都打印出来了:
PolarBear.compareTo
有没有办法访问Animal
的{{1}}?从逻辑上讲,我不希望能够比较compareTo
的动物品质以及PolarBear
品质吗?
答案 0 :(得分:7)
将bobo
对象转换为PolarBear
,Animal
或Comparable
并不重要,对象的运行时类型将因为您将其实例化为
PolarBear
Animal bobo = new PolarBear();
因此,当您致电.compareTo(wtv)
时,它会调用PolarBear
实施。
这就是多态性。阅读late binding,了解java中如何实现多态性。
如果要调用父类的compareTo(wtv)
方法,则必须在任何其他子类中执行super.compareTo(wtv)
'方法
答案 1 :(得分:2)
compareTo和inheritence通常是tricky business。理论上,拥有可比较的具体超类的子类会打破可比较的合同。例如 - 假设我有一个超类A,它通过检查字段a1和a1与其他A进行比较。现在让我们添加一个具有额外字段b1的子类B. anA.compareTo(aB)
将按a1和a2进行比较,而((A)aB).compareTo(anA)
则不会相同
关于你的问题 - 你可以通过做类似
super.compareTo(<something>)
但不是来自“外部”,因为你已经覆盖了这个方法。你有责任与你刚刚覆盖的方法保持与外界相同的“契约”。
答案 2 :(得分:1)
您可以随时在PolarBear中调用 super.compareTo(arg0)来调用Animal.compareTo中的逻辑。
答案 3 :(得分:0)
这很简单。底层对象是PolarBear类,您每次都要更改对象的接口(用于保存对象引用的Class)。
JVM在编译时检查接口中是否存在接口中的方法(用于保存对象引用的Class),但绑定是否在运行时发生,因为Child(PolearBear)具有该方法,因此它将始终运行这一点。
使用super.compareTo()来调用父方法。