繁体   English   中英

JAVA:当我调用 object 的 getter 方法时发生了什么,它实际上是从它的超类扩展方法

[英]JAVA: what happend when i call a getter method of a object which actually extend the method from it's superClass

我有两个 class

public class Person {
    public String name = "person";
    public String getName(){
      return name;
    };
}

public class Teacher extends Person{
    public String name ="teacher";

    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        System.out.println(teacher.getName());
    }
}

  1. 代码 teacher.getName() 的 output 是 "person" 为什么?

**无论名称属性的修改是私有的还是公共的,结果始终是“人”,但到目前为止我所学到的告诉我,如果子类从超类扩展,它也会包含超类的方法,所以当我调用该方法时子类object,方法中的名称应该是this.name,这应该是老师吧?,但为什么我仍然得到超类的名称? **

子类中名为name的变量隐藏了super class中的同名变量。参见https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#d5e12172

您可能希望在超类中只有一个字段name ,并希望在构造 object 时设置它:

class Person {
    private final String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}


class Teacher extends Person {
    public Teacher(String name) {
        super(name);
    }

    public static void main(String[] args) {
        Teacher teacher = new Teacher("teacher");
        System.out.println(teacher.getName());
    }
}

这基本上是范围界定的问题。 private变量只能由定义的 class 访问。在您的例子中,基数 class 负责实现 getter function,它只会知道自己的变量。

基础 class 不知道子类中定义的变量(这可以说是过于简单化了,下面的建议中有一些解释性细节,但至少应该让你走上正确的道路)。

如果您希望子类能够修改变量值,而不仅仅是 function,那么您需要执行以下操作之一:

  1. 使变量protected (仅对 class 及其子类可见),并在子类的构造函数中对其进行赋值。 或者,
  2. 在你的基础 class 中公开一个 setter function,并在你的构造函数中调用它。 如果您想限制对子类的访问并且不允许 package 之外的类修改它,则可以保护它。 或者,
  3. 只需覆盖子类中的 getter function,以便它返回子类的私有变量。 (此外,如果您不需要该值是可变的,您可以简单地return "teacher"; )。 如果这样做,请记住您正在分配一个碰巧共享相同名称的变量; 它与 state 的基类视图不同。
  4. (编辑添加)您还可以使逻辑在基类 class 构造函数中设置名称,并在任何基类中调用super(name) ,就像@tgdavies 所做的那样。 如果设置名称是所有子类的一个相当关键的行为,这个解决方案连同上面的#1 和#2,确保名称只有一个真实来源。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM