Java中的变量和方法阴影

时间:2013-03-10 08:43:55

标签: java static instance instance-variables shadowing

基本上我想知道为什么静态方法不能被实例方法遮蔽,(我知道为什么,它会在某些情况下导致模糊),而静态变量可以被实例变量遮蔽(它适用仅适用于子类)。

示例:

public class Apartment{

    static int area = 10;

    public static int getArea(){
        return area;
    }
}

class BedroomFlat extends Apartment {

    int area = 10;// no problem at all 

    public int getArea(){ // illegal line it cannot hide the super static method
        return area;
    }
}

因此,如果我尝试在超类中声明int area(实例变量)和static int area,它会产生错误但在子类中声明时不会发生,即使{{{ 1}}仍然可以从子类中看到。

尝试使用实例方法隐藏静态方法和尝试使用实例变量隐藏静态变量之间的行为方面究竟有什么不同。

提前致谢。

6 个答案:

答案 0 :(得分:2)

没有人可以继承静态方法和字段,因为它们属于类。

如果你是从父级覆盖getArea();,你试图创建具有相同签名的方法 - 这会导致编译错误。

答案 1 :(得分:1)

在子类(BedroomFlat)中,编译器不允许您声明与基类中静态方法名称相同的实例方法,因为方法覆盖仅适用于实例方法。扩展类只使实例方法可用于子类以进行重写(而不是类方法,即静态)。 此外,当您尝试声明具有与静态方法相同签名的方法时,编译器将抛出一个错误,指出您无法覆盖静态方法,因为重写发生在实例方法中。

但是编译器不会阻止你声明一个与超类中的静态变量同名的实例变量,因为变量不是覆盖的候选者。

答案 2 :(得分:0)

事情是:你根本没有在这里遮蔽任何东西......

您的实例变量可以直接访问我的命名和NORMALLY您必须编写类似ClassName.staticVar的内容来访问静态变量。 Java只允许您在引用静态变量时省略类名。

这说清楚了,不是吗?

答案 3 :(得分:0)

在Java中,静态方法和字段只属于类,因此它们不能被对象继承,否则会导致编译错误。

答案 4 :(得分:0)

我们知道子进程继承了父进程,但我们也知道静态方法无法被覆盖。因此,在这种情况下,您将在子项中使用两个具有相同方法签名的方法。这将产生问题,因为java不支持两个相同签名的方法,尽管这里有一个方法是静态的,另一个方法是非静态的。但对于静态变量,情况并非如此。

答案 5 :(得分:0)

我的猜测是,这给多态性带来了一些问题(或者至少是如何实现的)。假设你做了类似Apartment x = new BedroomFlat();的事情。调用方法getArea(),它不知道它是隐藏方法还是被覆盖,因为如果它是隐藏的(静态)它应该调用类Apartment中的那个,但是如果它被覆盖它应该调用实例一。

当然,通常应该避免这些情况(这会带来不必要的麻烦)。

编辑:我发现了这个链接,在页面底部,您可以看到静态和实例方法之间的方法隐藏/覆盖表。 Idk为什么会这样,但至少我们知道它写在某处(https://docs.oracle.com/javase/tutorial/java/IandI/override.html