【问题标题】:Inheritance and private instance variables继承和私有实例变量
【发布时间】:2012-12-03 00:35:06
【问题描述】:

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

谢谢

【问题讨论】:

  • 您的意思是Dog 类的equals 根本不用?如果没有,从您的代码中可以明显看出。

标签: java inheritance equals private


【解决方案1】:

@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。

【讨论】:

  • //Dog.equals(String)中还有一个问题// OP的q中哪里有这样的方法?还有什么会导致他的问题中的stackoverflow?
  • 我无法弄清楚为什么 q.equals(p) 会抛出异常,因为我只是在 Pet 中调用 equals 方法?
  • @StephenC 是的,我已经尝试过你所说的并且它有效,但我只是想弄清楚它为什么有效以及为什么我的方式会引发异常。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 2014-10-28
    • 2014-04-06
    • 2013-08-16
    • 2014-11-17
    • 2012-11-05
    • 2012-05-16
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    相关资源
    最近更新 更多