[英]Having 2 variables with the same name in a class that extends another class in Java
Following is a part of my code for a project: 以下是我的项目代码的一部分:
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;
}
}
I quickly realized that doing this will create two variables inside the Body class called x and two other variables in Body called y. 我很快意识到这样做会在Body类中创建两个名为x的变量,在Body中创建另外两个名为y的变量。 How is this even possible, and why on earth does Java even allow it?
这怎么可能,以及为什么Java甚至允许它呢?
I assume this is the correct code of class Body: 我假设这是类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;
}
}
Thanks for your time 谢谢你的时间
In a sense, you are overriding fields of the super class. 从某种意义上说,你是超越超级阶级的领域。 But it's far easier to do accidentally because there is no overloading of fields (you only have one variable of a given name, the type doesn't matter).
但是由于没有字段超载(你只有一个给定名称的变量,类型无关紧要),因此意外地做起来要容易得多。 This is referred to as variable 'hiding' or 'shadowing'.
这被称为变量'隐藏'或'阴影'。 So, you're correct, you'll end up with two fields with the same name.
所以,你是对的,你最终会得到两个同名的字段。
Your second example is correct. 你的第二个例子是正确的。 They are inherited from the super-class and since they are not declared private, they are visible to the subclass.
它们是从超类继承的,因为它们不是私有的,所以它们对子类是可见的。 It's generally bad practice to refer directly to a super-class's fields, and unless there is good reason, they should declared private.
直接引用超类的字段通常是不好的做法,除非有充分的理由,否则它们应该被声明为私有。 Your example of invoking the super constructor is the best approach.
调用超级构造函数的示例是最好的方法。
Also, if you hide a field with another of the same name, you can still refer to them as super.x, super.y, vs. this.x, this.y, you should avoid this situation if at all possible. 此外,如果您使用同名的另一个字段隐藏字段,您仍然可以将它们称为super.x,super.y,而不是this.x,this.y,如果可能的话,您应该避免这种情况。
Yes, you'll have two variables, with one hiding the other. 是的,你将有两个变量,一个隐藏另一个。 It makes sense to allow it for two reasons:
允许它有两个原因:
Base
and a derived class Derived
which the author of Base
has no idea about. Base
和派生类Derived
, Base
的作者根本不知道。 Should the author of Base
never be able to add any fields, just because a derived class might share the fields? Base
的作者是否应该能够添加任何字段,只是因为派生类可能共享字段? Or should Derived
stop compiling when the change to Base
doesn't actually affect the correctness? Base
的更改实际上不影响正确性时, Derived
是否应该停止编译? Further to what others have said: Is Body
a Point
? 继其他人所说的:
Body
是一个Point
吗? No, Body
has a position property of type Point
. 不,
Body
具有Point
类型的位置属性。 So Body
probably should not extend Point
. 所以
Body
可能不应该扩展Point
。 If you get rid of inheritance (of implementation) then you get rid of a lot of problems. 如果你摆脱继承(实现),那么你摆脱了很多问题。 That and use
private
(not protected
!) and final
liberally. 那和使用
private
(不受protected
!)和final
自由。
I quickly realized that doing this will create two variables inside the Body class called x and two other variables in Body called y.
我很快意识到这样做会在Body类中创建两个名为x的变量,在Body中创建另外两个名为y的变量。 How is this even possible, and why on earth does Java even allow it?
这怎么可能,以及为什么Java甚至允许它呢?
Actually no, you are not creating two variables with the same name, obviously a compiler should not and would not allow this. 实际上不,你没有创建两个具有相同名称的变量,显然编译器不应该也不允许这样做。
What you are doing is shadowing the existing variables defined as x
and y
, meaning that Body.x and Body.y are essentially overlapping the names for Point.x and Point.y, making the latter two variable completely inaccessible from the Body class ( link to Java Language Specification definition of "shadowing" ). 你正在做的是遮蔽定义为
x
和y
的现有变量,这意味着Body.x和Body.y基本上与Point.x和Point.y的名称重叠,使得后两个变量完全无法从Body类中访问( 链接到Java语言规范定义的“阴影” )。
Name shadowing is generally perceiving as a bad practice and a cause of bugs, and if you turn up the javac compiler warnings, the compiler will dutifully warn you about this. 名称阴影通常被认为是一种不良做法和错误原因,如果你打开javac编译器警告,编译器将尽职尽责地警告你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.