1

我无法弄清楚如何访问超类的私有实例变量。我在 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 类的 equal 方法。

谢谢

4

2 回答 2

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

于 2012-12-15T01:10:18.927 回答
1

如果你仔细看你的 Dog 类有两种equals方法:

  • equals(Pet other)形成超类
  • equals(Object obj)来自 Dog 类。

由于您使用d1.equals(d2)where d1 和 d2 是Dog实例,Java 将使用equals(Pet other)超类中的方法,在该方法中您只检查name相等性。

于 2012-12-15T01:13:21.257 回答