我有这段代码:
class X {
int x = 1;
}
class Y extends X {
int y = 2;
}
class Z extends Y {
int z = 3;
}
class A {
public Y metodo1(Y y) {
System.out.println("Metodo1 de A");
return new Y();
}
public Y metodo2(Y y) {
System.out.println("Metodo2 de A");
return new Y();
}
}
class B extends A {
public X metodo1(Y y) {
System.out.println("Metodo1 de B");
return new X();
}
public Z metodo2(Y y) {
System.out.println("Metodo2 de B");
return new Z();
}
public void metodo3() {
System.out.println("Metodo3 de B");
}
}
class C extends A{
public Y metodo1(X x) {
System.out.println("Metodo1 de C");
return new Y();
}
public Y metodo2(Z z) {
System.out.println("Metodo2 de C");
return new Z();
}
public void metodo3() {
System.out.println("Metodo3 de C");
}
}
public class DynamicBinding {
public static void main(String[] args) {
A b = new B();
A c = new C();
C c1 = new C();
X x1 = b.metodo1(new Y());
X x2 = b.metodo2(new Y());
b.metodo3();
X x3 = c.metodo1(new X());
X x4 = c.metodo2(new Z());
c.metodo3();
X x5 = c1.metodo1(new Y());
X x6 = c1.metodo1(new X());
}
}
我知道有一些错误,例如协变量返回类型
public X metodo1(Y y) {
System.out.println("Metodo1 de B");
return new X();
}
或
b.metodo3();
不存在,但是我的问题是这样的:X x5 = c1.metodo1(new Y());
X x6 = c1.metodo1(new X());
Eclipse不会向我显示任何错误,但是我认为它们具有协变量参数,而Java中是不允许的。我想念什么? (也许在
X x5 = c1.metodo1(new Y());
中它称为A的metodo1,但我不理解另一个)。谢谢!
最佳答案
子类中的方法不允许破坏超类中的合同,因此假设您拥有
Class SuperClass{
ReturnType method(ParameterType p) {..}
}
那么任何
SubClass
必须使用ReturnType method(ParameterType p) {..}
要么
ReturnTypeSubclass method(ParameterType p) {..}
这样可以确保使用类时,类型没有问题。合同没有用协变返回类型破坏,因为
ReturnTypeSubClass
是ReturnType
。如果像这样在
SubClass
中实现方法:AnyType method(ParameterTypeSubClass p) {..}
..您没有覆盖它。您正在超载。现在
SubClass
中有两种方法。一个是从SuperClass
继承的。想象一下,如果它覆盖了它,并且有人像这样使用了该类:
Super s = new SubClass;
s.method(new ParameterType());
将引发错误,因为覆盖方法无法采用
ParameterType
,并且合同将被破坏。