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. How is this even possible, and why on earth does Java even allow it?
I assume this is the correct code of class 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.
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
Base
and a derived class Derived
which the author of Base
has no idea about. Should the author of Base
never be able to add any fields, just because a derived class might share the fields? Or should Derived
stop compiling when the change to Base
doesn'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.
Further to what others have said: Is Body
a Point
? No, Body
has a position property of type Point
. So Body
probably 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 final
liberally.
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?
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").
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.