在一个扩展Java中另一个类的类中有两个具有相同名称的变量

Mar*_*son 12 java variables extends scope class

以下是我的项目代码的一部分:

public class Body extends Point{
    public double x, y, mass;

    public Body() {
        x = y = mass = 0;
    }

    public Body(double x, double y, double mass) {
        this.mass = mass;
        this.x = x;
        this.y = y;
    }
}

public class Point {
    public double x;
    public double y;

    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
}
Run Code Online (Sandbox Code Playgroud)

我很快意识到这样做会在Body类中创建两个名为x的变量,在Body中创建另外两个名为y的变量.这怎么可能,以及为什么Java甚至允许它呢?

我假设这是类Body的正确代码:

public class Body extends Point{
    public double mass;

    public Body() {
        super();
        mass = 0;
    }

    public Body(double x, double y, double mass) {
        super(x,y);
        this.mass = mass;
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢你的时间

Mar*_*ouf 13

从某种意义上说,你是超越超级阶级的领域.但是,由于没有字段的重载(你只有一个给定名称的变量,类型无关紧要),因此更容易意外地进行操作.这被称为变量'隐藏'或'阴影'.所以,你是对的,你最终会得到两个同名的字段.

你的第二个例子是正确的.它们是从超类继承的,因为它们不是私有的,所以它们对子类是可见的.直接引用超类的字段通常是不好的做法,除非有充分的理由,否则它们应该被声明为私有.调用超级构造函数的示例是最好的方法.

此外,如果您使用同名的另一个字段隐藏字段,您仍然可以将它们称为super.x,super.y,而不是this.x,this.y,如果可能的话,您应该避免这种情况.


Jon*_*eet 5

是的,你将有两个变量,一个隐藏另一个.允许它有两个原因:

  1. 假设你有一个基类Base和派生类Derived,作者Base并不知道.作者Base永远不能添加任何字段,只是因为派生类可能共享字段?或者应该Derived在更改时停止编译Base实际上不会影响正确性?
  2. 你的字段几乎总是私有的,此时名称是否重复并不重要 - "side"都不会知道另一个的变量.