2015-08-16 99 views
1

下面的代码无法编译:父类中的静态方法不允许子添加非静态方法?

public class Child extends Parent{ 

    void foo() {   
    } 
} 

class Parent{ 
    public static void foo(){} 
} 

为什么我不能在我的子类中声明的非静态方法?在这种情况下,由于方法是静态的,所以不允许重写,那么为什么编译器不允许我们声明实例方法?

+2

如果允许这样做,new Child()。foo()会做什么? –

+0

[JLS§8.4.8.1](https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8.1):“这是一个编译时错误如果一个实例方法_overrides_一个静态方法。“ – Seelenvirtuose

回答

3

因为子类固有来自父类的所有方法和字段。在这种情况下,在Child类中将会有两个Child#foo()方法,因为如果已经编译过,它将不会被覆盖。

+0

好的,明白了..谢谢你的支持:) – Harinder

3

这种方法具有相同签名的静态方法,因为你can't override static methods(它是仍然Parent的一部分,这Child仍然得到),你不能宣布另一foo在一个相同的签名孩子的方法。

更技术,the JLS specifies

它是一类的主体中的编译时错误两种方法使用倍率相当于签名声明为成员(§8.4.2)。

如果您更改了签名;也就是说,如果你在子类的方法中声明了一个参数,那么它就没问题。

+1

我知道,我有时候会挑剔,对不起。但引用的JLS段不是正确的。它处理_same_类中两个_declared_方法的情况。这里的情况是我们在父类中有一个方法,而在子类中有另一个方法。所描述的编译器错误由[JLS§8.4.8.1](https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8.1)处理。 – Seelenvirtuose

1

在覆盖它们时,不能更改对继承方法的访问 - 静态保持静态。 当在单个类中重载方法时适用同样的东西 - 您可以使用相同的方法名称,但方法需要接受不同的参数。

1

因为孩子从父母和自己识别foo()。所以你不能用你当前的代码创建。但是,你可以在你的孩子申报的新富()这样的:

public class Child extends Parent{ 


    public static void foo() { 
    } 
} 

class Parent{ 
    public static void foo(){ 
    } 
} 

更多细节在这里:你可以写在具有相同签名的一个超类中的子类一个新的静态方法,从而隐藏它http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html