web-dev-qa-db-ja.com

静的メソッドをオーバーライドしようとするとコンパイラーが文句を言わないのはなぜですか?

Javaの静的メソッドをオーバーライドできないことは知っていますが、誰かが次のコードを説明できますか?

_class A {
    public static void a() { 
        System.out.println("A.a()");
    }
}   

class B extends A {
    public static void a() {
        System.out.println("B.a()");
    }
}
_

クラスBのメソッドa()をどのようにオーバーライドできましたか?

34
user2395360

ここでは何もオーバーライドしませんでした。自分で確認するには、クラスBpublic static void a()の前に_@Override_注釈を付けてみてください。Javaはエラーをスローします。

クラスBの関数a()とは異なる(まったく関係がない)a()というクラスAの関数を定義したばかりです。

ただし、B.a()は親クラスの関数と同じ名前であるため、hidesA.a() [As Engが指摘しました。 Fouad]。実行時に、コンパイラは宣言された参照の実際のクラスを使用して、実行するメソッドを決定します。例えば、

_B b = new B();
b.a() //prints B.a()

A a = (A)b;
a.a() //print A.a(). Uses the declared reference's class to find the method.
_

Javaの静的メソッドをオーバーライドすることはできません。 staticメソッドとフィールドは、オブジェクトではなくクラスに関連付けられていることに注意してください。 (Smalltalkのような一部の言語では、これは可能です)。

ここにいくつかの良い答えが見つかりました: なぜJava静的メソッドのオーバーライドを許可しないのですか?

54
goblinjuice

それはhiding a method、Javaチュートリアル メソッドのオーバーライドと非表示

サブクラスがスーパークラスのクラスメソッドと同じシグネチャを持つクラスメソッドを定義する場合、サブクラスのメソッドはスーパークラスのメソッドを隠します。

9
Eng.Fouad

staticメソッドは継承されないため、そのBのメソッドの別個のコピー

staticは、classの状態ではなく、Objectに関連しています

6
Jigar Joshi

staticメソッドは継承されないため、メソッドa()をオーバーライドしませんでした。 @Override、あなたはエラーを見たでしょう。

A.Java:10: error: method does not override or implement a method from a supertype
    @Override
    ^
1 error

しかし、それは両方のクラスで同じシグネチャを持つ静的メソッドを定義することを止めません。

3
rgettman

メソッドはオーバーライドされたメソッドではありません。派生クラスのメソッドの前に@Overrideアノテーションを配置するだけです。コンパイル時エラーが発生します。 so Javaでは、静的メソッドをオーバーライドできません。

1
user1374185

Goblinjuiceの回答は受け入れられましたが、サンプルコードを改善できると思いました。

_public class StaticTest {
    public static void main(String[] args) {
        A.print();
        B.print();
        System.out.println("-");

        A a = new A();
        B b = new B();
        a.print();
        b.print();
        System.out.println("-");

        A c = b;
        c.print();
    }
}

class A {
    public static void print() {
        System.out.println("A");
    }
}

class B extends A {
    public static void print() {
        System.out.println("B");
    }
}
_

生産物:

_A
B
-
A
B
-
A
_

Bがprint()をオーバーライドした場合、最終行にBを書き込みます。

1
David Newcomb

静的メソッドはそのクラス名によって呼び出されるため、クラスオブジェクトを作成する必要はありません。クラスオブジェクトを作成するだけで、静的をオーバーライドできません。

例えば

_class AClass{
public static void test(){

 } 
}

class BClass extends AClass{
public static void test(){}

}

class CClass extends BClass{
public static void main(String args[]){

AClass aclass=new AClass();

aclass.test(); // its wrong because static method is called 
               // by its class name it can't accept object
}
}
_

私たちはただそれを呼ぶ

AClass.test();

は、静的クラスがオーバーライドされた場合、それをどのように計算するかをオーバーライドできないことを意味します。

0
javaCode555