web-dev-qa-db-ja.com

静的メソッドはJavaで継承されますか?

私は読んでいたJava™SCJP認定のためのプログラマーズガイド Khalid Mughalによる。

継承の章では、

メンバーの継承は、宣言されたアクセシビリティに密接に関係しています。スーパークラスのメンバーがサブクラスの単純な名前でアクセスできる場合(スーパーのような追加の構文を使用せずに)、そのメンバーは継承されたと見なされます

また、静的メソッドは継承されないことにも言及しています。ただし、以下のコードは完全に問題ありません。

class A
{
    public static void display()
    {
        System.out.println("Inside static method of superclass");
    }
}

class B extends A
{
    public void show()
    {
        // This works - accessing display() by its simple name -
        // meaning it is inherited according to the book.
        display();
    }
}

クラスBdisplay()を直接使用するにはどうすればよいですか?さらに、B.display()も機能します。

本の説明はインスタンスメソッドにのみ適用されますか?

125
Algorithmist

アクセス可能なすべてのメソッドはサブクラスに継承されます。

太陽からJava チュートリアル

サブクラスは、サブクラスがどのパッケージにあるかに関係なく、その親のすべてのパブリックメンバーと保護メンバーを継承します。サブクラスが親と同じパッケージにある場合、親のパッケージプライベートメンバーも継承します。継承されたメンバーをそのまま使用したり、置き換えたり、非表示にしたり、新しいメンバーで補足したりできます。

継承された静的(クラス)メソッドと継承された非静的(インスタンス)メソッドとの唯一の違いは、同じシグネチャで新しい静的メソッドを記述すると、古い静的メソッドはオーバーライドされずに非表示になるだけです。

page のオーバーライドと非表示の違いから。

非表示と上書きの区別には重要な意味があります。呼び出されるオーバーライドされたメソッドのバージョンは、サブクラス内のものです。呼び出される隠しメソッドのバージョンは、スーパークラスから呼び出されるかサブクラスから呼び出されるかによって異なります

164
yincrash

その本が本当に言っているのなら、それは間違っています。[1]

Java言語仕様#8.4.8 状態:

8.4.8継承、オーバーライド、および非表示

クラスCは、直接のスーパークラスから、次のすべてが当てはまるスーパークラスのすべての具象メソッドm(静的およびインスタンスの両方)を継承します。

  • mは、Cの直接スーパークラスのメンバーです。

  • mはpublic、protected、またはCと同じパッケージ内のパッケージアクセスで宣言されています。

  • Cで宣言されたメソッドには、mの署名のサブ署名(8.4.2)である署名がありません。

[1]私のコピー、第1版、2000年には、そうは言っていません。

14
user207421

次のコードの違いが発生する可能性がありますが、これはコードをわずかに変更したものです。

class A {
    public static void display() {
        System.out.println("Inside static method of superclass");
    }
}

class B extends A {
    public void show() {
        display();
    }

    public static void display() {
        System.out.println("Inside static method of this class");
    }
}

public class Test {
    public static void main(String[] args) {
        B b = new B();
        // prints: Inside static method of this class
        b.display();

        A a = new B();
        // prints: Inside static method of superclass
        a.display();
    }
}

これは、静的メソッドがクラスメソッドであるためです。

A.display()およびB.display()は、それぞれのクラスのメソッドを呼び出します。

8
Gaurav

B.display()は、静的宣言によってメソッド/メンバーが特定のクラスインスタンス(別名オブジェクト)ではなくクラスに属するため、機能します。それについてもっと読むことができます こちら

別の注意点は、静的メソッドをオーバーライドできないことです。サブクラスに同じシグネチャで静的メソッドを宣言させることができますが、その動作は予想とは異なる場合があります。これがおそらく、継承と見なされない理由です。問題のあるシナリオと説明 こちら を確認できます。

5
Kai

この概念は見た目ほど簡単ではありません。継承なしで静的メンバーにアクセスできます。これはHasA関係です。親クラスも拡張することで、静的メンバーにアクセスできます。これは、ISA関係(継承)であることを意味するものではありません。実際には静的メンバーはクラスに属し、静的はアクセス修飾子ではありません。アクセス修飾子が静的メンバーへのアクセスを許可する限り、他のクラスで使用できます。パブリックの場合と同じように、同じパッケージ内およびパッケージ外からアクセスできます。プライベートの場合、どこでも使用できません。デフォルトでは、パッケージ内でのみ使用できます。しかし、protectedの場合、スーパークラスを拡張する必要があります。したがって、静的メソッドを他のクラスに取得することは、静的であることに依存しません。 Access修飾子に依存します。したがって、私の意見では、静的メンバーはアクセス修飾子が許可すればアクセスできます。それ以外の場合は、Hasa-relationで使用するように使用できます。そして、関係は継承ではありません。繰り返しますが、静的メソッドをオーバーライドすることはできません。他のメソッドを使用できるが、オーバーライドできない場合は、HasA-relationです。それらをオーバーライドできない場合、それは継承ではないので、ライターは100%正しかったです。

2
Noman_ibrahim

すべてのパブリックメンバーと保護メンバーはどのクラスからも継承できますが、デフォルトまたはパッケージメンバーはスーパークラスと同じパッケージ内のクラスからも継承できます。静的メンバーか非静的メンバーかに依存しません。

しかし、静的メンバー関数が動的バインディングに参加しないことも事実です。その静的メソッドのシグネチャが親クラスと子クラスの両方で同じ場合、ポリモーフィズムではなくシャドウイングの概念が適用されます。

0
shubham

Javaの静的メソッドは継承されますが、オーバーライドできません。サブクラスで同じメソッドを宣言する場合、スーパークラスメソッドをオーバーライドする代わりに非表示にします。静的メソッドはポリモーフィックではありません。コンパイル時に、静的メソッドは静的にリンクされます。

例:

public class Writer {
    public static void write() {
        System.out.println("Writing");
    }
}

public class Author extends Writer {
    public static void write() {
        System.out.println("Writing book");
    }
}

public class Programmer extends Writer {

    public static void write() {
        System.out.println("Writing code");
    }

    public static void main(String[] args) {
        Writer w = new Programmer();
        w.write();

        Writer secondWriter = new Author();
        secondWriter.write();

        Writer thirdWriter = null;
        thirdWriter.write();

        Author firstAuthor = new Author();
        firstAuthor.write();
    }
}

次のものが得られます。

Writing
Writing
Writing
Writing book
0
Aleksey Bykov

静的メソッドはサブクラスで継承されますが、ポリモーフィズムではありません。静的メソッドの実装を記述するとき、親のクラスメソッドは上書きされず、隠されます。継承されていない場合、classname.staticMethodname();なしでどのようにアクセスできるかを考えてください。

0
user4016405

静的メソッドをオーバーライドできますが、ポリモーフィズムを使用しようとすると、クラススコープに従って動作します(通常期待されるものとは異なります)。

public class A {

    public static void display(){
        System.out.println("in static method of A");
    }
}

public class B extends A {

    void show(){
        display();
    }

     public static void display(){
        System.out.println("in static method of B");
    }

}
public class Test {

    public static void main(String[] args){
        B obj =new B();
        obj.show();

        A a_obj=new B();
        a_obj.display();


    }


}

最初の場合、o/pは「Bの静的メソッド」#オーバーライド成功2番目の場合、o/pは「Aの静的メソッド」#静的メソッド-ポリモーフィズムは考慮されません

0
Manav Garekar

静的メソッドはJavaで継承されますが、多態性には関与しません。静的メソッドをオーバーライドしようとすると、スーパークラスの静的メソッドをオーバーライドするのではなく、単に非表示にします。

0
Praveen Kumar