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

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;
    }
}

我很快意识到这样做会创造 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;
    }
}

谢谢你的时间

有帮助吗?

解决方案

在某种意义上,你将覆盖超类的字段。但它更容易不小心做是因为没有域的超载(你只有一个给定名称的一个变量,类型并不重要)。这被称为可变“隐藏”或“阴影”。所以,你是正确的,你会用两个名称相同的字段结束。

您第二个例子是正确的。它们从超类继承和因为它们不声明为private,他们是在子类中可见。这是一般不好的做法,直接引用一个超一流的领域,除非有很好的理由,就应该声明为private。您调用超级构造函数的例子是最好的办法。

另外,如果你隐藏字段与另一个同名的,你仍然可以把它们称为super.x,super.y,与this.x,this.y,你应该避免这种情况,如果在所有可能。

其他提示

是的,你只有两个变量,有一个隐藏的。它是有意义的允许它的原因有两个:

  1. 假设你已经有了一个基类 Base 和一个源类 Derived 它的作者 Base 有没有想法.应该提交人的 Base 永远不能加入的任何领域,仅仅因为一个源类 可能会 分享的领域?或者应该 Derived 停止编制当的改变 Base 实际上并不影响的正确性?
  2. 你的领域应几乎总是私人的,在这一点上,不管名称是否重复或不-不是"副"将知道有关的变量。

此外,以其他人所说:是Body一个Point?不,Body有型Point的位置属性。所以Body或许不应该延长Point。如果你摆脱继承(执行),那么你摆脱了很多的问题。这和使用private(未protected!)和final宽松。

我很快意识到这样做会在 Body 类中创建两个名为 x 的变量,并在 Body 类中创建另外两个名为 y 的变量。这怎么可能?Java 到底为什么允许这样做?

实际上不,您没有创建两个具有相同名称的变量,显然编译器不应该也不会允许这样做。

你什么 所做的就是隐藏定义为的现有变量 xy, ,这意味着 Body.x 和 Body.y 本质上与 Point.x 和 Point.y 的名称重叠,使得后两个变量完全无法从 Body 类访问(链接到“遮蔽”的 Java 语言规范定义).

名称隐藏通常被认为是一种不好的做法和错误的原因,如果您打开 javac 编译器警告,编译器将尽职尽责地警告您这一点。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top