变量隐藏在java中

时间:2018-04-09 20:04:57

标签: java

请看下面的代码:

class Rodent {

    protected int tailLength = 4;

    public void getRodentDetails() {
        System.out.println(this.tailLength);
    }
}

public class Mouse extends Rodent {
    protected  int tailLength = 8;

    public static void main(String[] args) {
        Mouse mouse = new Mouse();
        mouse.getRodentDetails();
    }
}

现在继承getRodentDetails()。 当Mouse引用调用时,this.tailLength应该打印8而不是4,因为父级tailLength隐藏在鼠标中。

为什么打印4?

编辑:问题不在于什么是变量隐藏,也不在于如何尝试覆盖变量。最接近的答案是JB Nizet在评论中给出的,我将其作为答案进行了扩展。

4 个答案:

答案 0 :(得分:2)

在Java中,您可以使用overwrite方法,而不是属性。但你可以隐藏它们。

因此,无论何时在tailLength类内部调用Mouse属性,您都会隐藏tailLength类的Rodent属性,并使用Mouse中的值类。

如果要覆盖此值,则应使用此结构:

class Rodent {
    // we add final to make sure value is always set
    protected final int tailLength;

    // default constructor
    protected Rodent() { this(4); }
    // use to overwrite tailLength  value
    protected Rodent(int tailLength ) { this.tailLength =tailLength; }

    public void getRodentDetails() {
        System.out.println(this.tailLength);
    }
}

鼠标类:

public class Mouse extends Rodent {
    public Mouse (){
      super(8);
    }
    ...
}

这样你就可以设置尾巴长度而不会有任何覆盖,只需使用OOP。

答案 1 :(得分:1)

嗯,这是因为static binding

  

1)Java中的静态绑定发生在Dynamic的编译时   绑定发生在运行时。

     

2)私有方法,最终方法和静态方法和变量使用静态绑定,并在虚拟方法时由编译器绑定   在运行时根据运行时对象进行绑定。

     

3)静态绑定使用Type(Java中的Class)信息进行绑定   而动态绑定使用Object来解析绑定。

     

4)在重写时使用静态绑定绑定重载方法   方法在运行时使用动态绑定进行绑定。

所以,

protected int tailLength = 4;

public void getRodentDetails() {
    System.out.println(this.tailLength);
}

在此代码中,tailLength仅在编译时与Rodent类的tailLength变量相关联。

为什么this没有影响它? 这是因为this在运行时被解析为内存地址。

有些人说这是由于变量隐藏,但由于静态绑定而发生变量隐藏。

答案 2 :(得分:0)

变量不会被覆盖,就像你应该在构造函数

中初始化它们一样
    public Mouse (){
     super.tailLength = 8;
    }

通过定义它将生成鼠标类未知的其他变量

答案 3 :(得分:0)

简而言之,来自Oracle Documentation我的重点):

  

在一个类中,一个字段与相同的名称作为字段中的字段   超类隐藏超类的字段,即使它们的类型是   不同。

由此我们了解到成员字段不能像方法一样被覆盖。 超级tailLength中的Rodent字段已隐藏,无法以多态方式进行访问。

在超类tailLength中访问Rodent的一种方法是通过强制转换,例如:

System.out.println(((Rodent)mouse).tailLength);