在 Java 中扩展另一个类的类中有 2 个同名变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/772663/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Having 2 variables with the same name in a class that extends another class in Java
提问by Martin Andersson
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 twovariables inside the Body class called x and two other variables in Body called y. How is this even possible, and why on earth does Java even allow it?
我很快意识到这样做会在 Body 类中创建两个名为 x 的变量,以及在 Body 中创建两个名为 y 的其他变量。这怎么可能,为什么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
谢谢你的时间
采纳答案by Mark Renouf
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、vs. this.x、this.y,如果可能的话,你应该避免这种情况。
回答by Jon Skeet
Yes, you'll have two variables, with one hiding the other. It makes sense to allow it for two reasons:
是的,您将有两个变量,一个隐藏另一个。允许它有两个原因是有意义的:
- Suppose you've got a base class
Baseand a derived classDerivedwhich the author ofBasehas no idea about. Should the author ofBasenever be able to add any fields, just because a derived class mightshare the fields? Or shouldDerivedstop compiling when the change toBasedoesn't actually affect the correctness? - Your fields should almost always be private, at which point it doesn't matter whether the names are duplicated or not - neither "side" will know about the variables of the other.
- 假设您有一个作者不知道的基类
Base和派生类。作者是否应该永远无法添加任何字段,仅仅因为派生类可能共享这些字段?或者应该在更改为实际上不影响正确性时停止编译?DerivedBaseBaseDerivedBase - 您的字段应该几乎总是私有的,此时名称是否重复并不重要 - “一方”都不知道另一方的变量。
回答by Tom Hawtin - tackline
Further to what others have said: Is Bodya Point? No, Bodyhas a position property of type Point. So Bodyprobably should not extend 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 finalliberally.
继其他人所说:是Body一个Point?不,Body具有类型的位置属性Point。所以Body大概不应该扩展Point。如果你摆脱了继承(实现),那么你就摆脱了很多问题。那和使用private(不是protected!)和final自由。
回答by matt b
I quickly realized that doing this will create two variables inside the Body class called x and two other variables in Body called y. How is this even possible, and why on earth does Java even allow it?
我很快意识到这样做会在 Body 类中创建两个名为 x 的变量,以及在 Body 中创建两个名为 y 的其他变量。这怎么可能,为什么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 aredoing is shadowing the existing variables defined as xand 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").
您正在做的是隐藏定义为xand的现有变量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 编译器警告,编译器会尽职尽责地警告你这一点。

