关于 Java 中协变参数的问题
Question about covariant parameters in Java
我有这段代码:
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());
}
}
我知道有一些错误,例如
中的协变 return 类型
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 中的方法破坏超级 class 中的约定,所以假设您有
Class SuperClass{
ReturnType method(ParameterType p) {..}
}
然后任何 SubClass
必须使用
覆盖方法
ReturnType method(ParameterType p) {..}
或
ReturnTypeSubclass method(ParameterType p) {..}
这确保了在使用 class 时,类型没有问题。协变 return 类型没有违反合同,因为 ReturnTypeSubClass
是 ReturnType
.
如果您像这样在 SubClass
中实现方法:
AnyType method(ParameterTypeSubClass p) {..}
..你没有覆盖它。你超载了它。 SubClass
中现在有两个方法。一个是继承自SuperClass
.
想象一下,如果它覆盖了它并且有人像这样使用 class:
Super s = new SubClass;
s.method(new ParameterType());
会抛出一个错误,因为覆盖方法将无法接受 ParameterType
,并且合同会被破坏。
我有这段代码:
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());
}
}
我知道有一些错误,例如
中的协变 return 类型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 中的方法破坏超级 class 中的约定,所以假设您有
Class SuperClass{
ReturnType method(ParameterType p) {..}
}
然后任何 SubClass
必须使用
ReturnType method(ParameterType p) {..}
或
ReturnTypeSubclass method(ParameterType p) {..}
这确保了在使用 class 时,类型没有问题。协变 return 类型没有违反合同,因为 ReturnTypeSubClass
是 ReturnType
.
如果您像这样在 SubClass
中实现方法:
AnyType method(ParameterTypeSubClass p) {..}
..你没有覆盖它。你超载了它。 SubClass
中现在有两个方法。一个是继承自SuperClass
.
想象一下,如果它覆盖了它并且有人像这样使用 class:
Super s = new SubClass;
s.method(new ParameterType());
会抛出一个错误,因为覆盖方法将无法接受 ParameterType
,并且合同会被破坏。