Java 重写的等于方法不';我没接到电话
考虑以下类别:Java 重写的等于方法不';我没接到电话,java,oop,inheritance,overriding,Java,Oop,Inheritance,Overriding,考虑以下类别: public class Base { protected int i = 0; public Base(int i) { this.i = i; } public Base(Base b) { this(b.i); } public Base foo() { return new Base(this); } } public class Sub extends B
public class Base {
protected int i = 0;
public Base(int i) {
this.i = i;
}
public Base(Base b) {
this(b.i);
}
public Base foo() {
return new Base(this);
}
}
public class Sub extends Base {
public Sub(int i) {
super(i);
}
public Sub(Sub s) {
super(s.i * 2);
}
public Base foo() {
return this;
}
@Override
public boolean equals(Object o) {
return ((Sub) o).i == this.i;
}
public static void main(String[] args) {
Base b1 = new Base(1);
Base b2 = b1;
Base b3 = b2.foo();
Base b4 = new Sub(1);
Base b5 = b4.foo();
System.out.println(b1.equals(b3));
}
}
打印结果为false
。我注意到被重写的方法equals(Object o)
从未被捕获,我当然怀疑这就是问题所在(否则它会打印true
)
这是为什么?您正在调用
b1。equals(b3)
-b1
是Base
的实例,而不是Sub
,因此无法调用重写方法
见鬼,即使是b3.equals(b1)
也不会在Sub
上调用任何东西,因为b3
也引用了Base
的实例
只有
b4
和b5
引用了Sub
的实例,因此只有b4.equals(…)
或b5.equals(…)
将调用重写的方法。此外,由于您在equals
方法中无条件地进行强制转换,b4.equals(b1)
(例如)将抛出异常,而不是返回false您正在调用的b1.equals(b3)
-b1
是Base
的实例,而不是Sub
,因此,无法调用重写方法
见鬼,即使是b3.equals(b1)
也不会在Sub
上调用任何东西,因为b3
也引用了Base
的实例
只有b4
和b5
引用了Sub
的实例,因此只有b4.equals(…)
或b5.equals(…)
将调用重写的方法。此外,由于您在equals
方法中进行无条件强制转换,b4.equals(b1)
(例如)将抛出异常,而不是返回false让我们看看您的代码(在主方法中)是如何运行的
Base b1=新的Base(1)代码>:-创建新的基本(1)对象,引用为b1
。让我们将此对象作为第一个对象调用
Base b2=b1代码>:-创建一个基类型引用变量并分配b1
变量的值,以便b1和b2引用同一个对象(第一个对象)
Base b3=b2.foo()
:-创建一个基类型引用变量b3。
foo()
调用第一个基对象中的方法,并返回一个新的基对象(第二个对象),其中它的i属性值=第一个对象的i属性值
Base b4=新子节点(1)代码>:-创建新的子(1)对象,引用为b4
。让我们将此对象称为第三个对象
Base b5=b4.foo()
:-创建一个基类型引用变量b5。
foo()
调用第三个对象(Sub)中的方法,并将其自身的引用作为基类型返回。Sub可以返回自己的引用作为基,因为基是它的超类
b1.equals(b3)
:-现在您已经调用了b1
引用的对象的equals方法b1
指的是Base
类型对象(第一个对象)。运行基本对象的equals方法。它具有默认的equals方法。(重写的方法位于子对象中,而这不是子对象。)默认等于方法检查它们的哈希代码是否相同。b1是第一个对象,b3是第三个对象。所以b1和b3不相等
所以输出应该是false
这里没有发生任何压倒一切的事情
如果按以下方式更改代码,则可以获得覆盖的输出
Base b1 = new Sub(1);
Base b3 = b1.foo();
Base b4 = new Sub(1);
Base b5 = b4.foo();
System.out.println(b4.equals(b3));
让我们看看您的代码(在main方法中)是如何运行的
Base b1=新的Base(1)代码>:-创建新的基本(1)对象,引用为b1
。让我们将此对象作为第一个对象调用
Base b2=b1代码>:-创建一个基类型引用变量并分配b1
变量的值,以便b1和b2引用同一个对象(第一个对象)
Base b3=b2.foo()
:-创建一个基类型引用变量b3。
foo()
调用第一个基对象中的方法,并返回一个新的基对象(第二个对象),其中它的i属性值=第一个对象的i属性值
Base b4=新子节点(1)代码>:-创建新的子(1)对象,引用为b4
。让我们将此对象称为第三个对象
Base b5=b4.foo()
:-创建一个基类型引用变量b5。
foo()
调用第三个对象(Sub)中的方法,并将其自身的引用作为基类型返回。Sub可以返回自己的引用作为基,因为基是它的超类
b1.equals(b3)
:-现在您已经调用了b1
引用的对象的equals方法b1
指的是Base
类型对象(第一个对象)。运行基本对象的equals方法。它具有默认的equals方法。(重写的方法位于子对象中,而这不是子对象。)默认等于方法检查它们的哈希代码是否相同。b1是第一个对象,b3是第三个对象。所以b1和b3不相等
所以输出应该是false
这里没有发生任何压倒一切的事情
如果按以下方式更改代码,则可以获得覆盖的输出
Base b1 = new Sub(1);
Base b3 = b1.foo();
Base b4 = new Sub(1);
Base b5 = b4.foo();
System.out.println(b4.equals(b3));