我无法弄清楚如何访问超类的私有实例变量。 我在Dog类中编写一个equals方法,比较一下名称和品种是否相同,但name是Pet内部的私有实例变量(Dog继承)。
这是我的代码:
public class Pet {
private String name;
public Pet(){
name = "";
}
public Pet(String name){
this.name = name;
}
public boolean equals(Pet other){
return this.name.equals(other.name);
}
}
和我的狗课:
public class Dog extends Pet {
private String breed;
public Dog(String name, String breed) {
super(name);
this.breed = breed;
}
public Dog(){
breed = "";
}
@Override
public boolean equals(Object obj){
if(obj == null){
return false;
}
if(obj.getClass() != this.getClass()){
return false;
}else{
Pet p = (Pet)obj;
Pet q = (Pet)this;
Dog temp = (Dog)obj;
boolean name = q.equals(p);
boolean bred = breed.equals(temp.breed);
return name && bred;
}
}
}
在我的主要课程中:
Dog d1 = new Dog("Harry", "Puggle");
Dog d2 = new Dog("Harry", "Pug");
System.out.println(d1.equals(d2));
出于某种原因,它一直使用我的Pet课程相同的方法。
由于
答案 0 :(得分:2)
@Pshemo已找出问题的直接原因。您的Pet.equals(Object)
不会覆盖`Dog.equals(String)
,因为签名不匹配。并且您的d1.equals(d2)
调用绑定到最匹配的方法签名,该签名是Pet
形式参数而不是Object
形式参数。
但是一旦你纠正了这个问题,Dog.equals(String)
方法就会出现另一个问题:
Pet p = (Pet)obj;
Pet q = (Pet)this;
boolean name = q.equals(p);
当您修复Pet.equals的签名时,这将导致对Dog.equals ...和StackOverflowError
的递归调用。 (Dog.equals将调用Dog.equals,它将调用Dog.equals,其中......)。基本上,q.equals
与当前正在执行的方法相同。类型转换没有做任何事......
将其更改为:
Pet p = (Pet)obj;
boolean name = super.equals(p);
以这种方式使用的super
关键字会调用equals
方法的重写版本。
我无法弄清楚如何访问超类的私有实例变量。
这与导致问题的原因不同。但答案是,如果您希望子类方法能够访问父类中的private
变量,那么您需要将getter和/或setter方法添加到父类,或者更改访问权限变量(通常)protected
。
答案 1 :(得分:1)
如果仔细观察,您的Dog课程有两种equals
方法:
equals(Pet other)
形成超类equals(Object obj)
。 由于您正在使用d1.equals(d2)
,其中d1和d2是Dog
个实例,Java将使用超类中的equals(Pet other)
方法,其中您只检查name
相等性。