java重载Object中equals()的方法时的问题

2024-11-09 02:57:42
推荐回答(2个)
回答1:

先看你的重载方法的:
public boolean equals(Circle circle)
而Object里的equals是:
public boolean equals(Object obj)

这两个方法的参数不同,所以Circle里的这个equals方法并没有覆盖object里的equals方法,而是增加了一个新的equlas方法,这个方法的参数是一个Circle引用,Circle还有1个继承自object的equals方法,这个方法的参数是一个Object引用。

1.Object circle1 = new Circle();//这里Object改成Circle输出true,为什么?

当这里是Circle circle1 = new Circle();Circle circle2 = new Circle()时,circle1.equals(circle2)这一句传递给equlas的是一个Circle引用,所以调用的是自己的equals(Circle circle)方法,这个方法检测的是两个Circle的radius值,相等则为True。Circle的radius已在类中被初始化为1,所以这里输出true。

当这里是Object circle1 = new Circle(); Object circle2 = new Circle();时,circle1.equals(circle2)这一句传递给equlas的是一个Object引用,所以调用的是Object的equals(Object obj)方法,显然返回false。

当这里是Circle circle1 = new Circle(); Object circle2 = new Circle();时,circle1.equals(circle2)这一句传递给equlas的是一个Object引用,所以调用的是继承自Object的equals(Object obj)方法,显然返回false。

当这里是Object circle1 = new Circle(); Circle circle2 = new Circle();时,circle1.equals(circle2)这一句传递给equlas的是一个Circle引用。circle1是Object类型,对一个父类引用来说,即使赋给它子类的对象也无法调用父类没有定义过的函数,也就是说equals(Circle circle)这个方法对circle1来说就不存在,而Circle也是一个Object,所以调用的是Object的equals(Object obj)方法,显然返回false。

2. System.out.println(circle1);//为什么不能看到radius变量?不是父类引用指向子类对象吗?

Java中绑定有两种形式静态绑定static-binding(早绑定early-binding)和动态绑定dynamic-binding(晚绑定late-binding,或运行时绑定runtime-binding)。静态绑定是在编译时绑定,而动态绑定是在运行时根据对象的实际情况来选择绑定父类或者是某个子类的方法。Java中成员变量是静态绑定的,方法是动态绑定的。在进行“向上转型”的时候子类会覆盖父类的实例方法而不会覆盖父类的成员变量。父类的成员变量还是父类的成员变量,
用Object circle1 = new Circle()向上转型,circle是个object,根本就没有radius这个成员变量,所以看不到。
记住一点,多态仅仅针对的是方法。

3.书上说在重载Object中equals()的方法时必须把里面的形参声明为Object,这里参数写成Object 不就不能用.radius了吗?

重载equals时,必须把参数声明为Object,否则不能覆盖父类的equals,造成上面第一条的结果。
像下面这样的equals,来自于Core Java卷一:

public boolean equals(Object obj)
{
if (this == obj) return true; //如果引用同一个对象直接返回true
if (obj == null) return false; //如果obj为null,直接返回false
if (getClass() != obj.getClass()) return false; //如果不属于同一个类的话直接返回false
Circle other = (Circle) obj; //强制转换为Circle,才能访问radius
return radius == other.radius; //比较radius
}

回答2:

虽然父类变量可以用子类初始化,但是该变量不能引用子类多出来的变量及方法.即在Object类中没radius这个变量,所以即使circle1变量用Circle类来初始化,也不能访问radius这个变量.