在 Java 中扩展另一个类的类中有 2 个同名变量
题
以下是我的项目代码的一部分:
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,你应该避免这种情况,如果在所有可能。
其他提示
是的,你只有两个变量,有一个隐藏的。它是有意义的允许它的原因有两个:
- 假设你已经有了一个基类
Base
和一个源类Derived
它的作者Base
有没有想法.应该提交人的Base
永远不能加入的任何领域,仅仅因为一个源类 可能会 分享的领域?或者应该Derived
停止编制当的改变Base
实际上并不影响的正确性? - 你的领域应几乎总是私人的,在这一点上,不管名称是否重复或不-不是"副"将知道有关的变量。
此外,以其他人所说:是Body
一个Point
?不,Body
有型Point
的位置属性。所以Body
或许不应该延长Point
。如果你摆脱继承(执行),那么你摆脱了很多的问题。这和使用private
(未protected
!)和final
宽松。
我很快意识到这样做会在 Body 类中创建两个名为 x 的变量,并在 Body 类中创建另外两个名为 y 的变量。这怎么可能?Java 到底为什么允许这样做?
实际上不,您没有创建两个具有相同名称的变量,显然编译器不应该也不会允许这样做。
你什么 是 所做的就是隐藏定义为的现有变量 x
和 y
, ,这意味着 Body.x 和 Body.y 本质上与 Point.x 和 Point.y 的名称重叠,使得后两个变量完全无法从 Body 类访问(链接到“遮蔽”的 Java 语言规范定义).
名称隐藏通常被认为是一种不好的做法和错误的原因,如果您打开 javac 编译器警告,编译器将尽职尽责地警告您这一点。