[英]Having 2 variables with the same name in a class that extends another class in Java
以下是我的项目代码的一部分:
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;
}
}
谢谢你的时间
从某种意义上说,你是超越超级阶级的领域。 但是由于没有字段超载(你只有一个给定名称的变量,类型无关紧要),因此意外地做起来要容易得多。 这被称为变量'隐藏'或'阴影'。 所以,你是对的,你最终会得到两个同名的字段。
你的第二个例子是正确的。 它们是从超类继承的,因为它们不是私有的,所以它们对子类是可见的。 直接引用超类的字段通常是不好的做法,除非有充分的理由,否则它们应该被声明为私有。 调用超级构造函数的示例是最好的方法。
此外,如果您使用同名的另一个字段隐藏字段,您仍然可以将它们称为super.x,super.y,而不是this.x,this.y,如果可能的话,您应该避免这种情况。
是的,你将有两个变量,一个隐藏另一个。 允许它有两个原因:
Base
和派生类Derived
, Base
的作者根本不知道。 Base
的作者是否应该能够添加任何字段,只是因为派生类可能共享字段? 或者,当对Base
的更改实际上不影响正确性时, Derived
是否应该停止编译? 继其他人所说的: 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编译器警告,编译器将尽职尽责地警告你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.