Having 2 variables with the same name in a class that extends another class in Java

无人久伴 提交于 2019-12-18 14:54:27

问题


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


回答1:


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.




回答2:


Yes, you'll have two variables, with one hiding the other. It makes sense to allow it for two reasons:

  1. 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?
  2. 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.



回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/772663/having-2-variables-with-the-same-name-in-a-class-that-extends-another-class-in-j

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!