24

子静的メソッドから超静的メソッドを呼び出すことは可能ですか?

つまり、一般的な方法で、これまでのところ、次のようになっています。

public class BaseController extends Controller {
    static void init() {
        //init stuff
    }
}

public class ChildController extends BaseController {
    static void init() {
        BaseController.loadState();
        // more init stuff
    }

}

動作しますが、super.loadState()を呼び出すなど、一般的な方法で実行したいのですが、動作しないようです...

4

6 に答える 6

17

Javaでは、静的メソッドをオーバーライドすることはできません。その理由はここできちんと説明されています

したがって、参照されているオブジェクトには依存しません。しかし、代わりに、それは参照のタイプに依存します。したがって、静的メソッドは別の静的メソッドを非表示にし、それをオーバーライドしないと言われます。

例(猫は動物のサブクラスです):

public class Animal {
    public static void hide() {
        System.out.format("The hide method in Animal.%n");
    }
    public void override() {
        System.out.format("The override method in Animal.%n");
    }
}

public class Cat extends Animal {
    public static void hide() {
        System.out.format("The hide method in Cat.%n");
    }
    public void override() {
        System.out.format("The override method in Cat.%n");
    }
}

メインクラス:

public static void main(String[] args) {
    Cat myCat = new Cat();
    System.out.println("Create a Cat instance ...");
    myCat.hide(); 
    Cat.hide();
    myCat.override();  

    Animal myAnimal = myCat;
    System.out.println("\nCast the Cat instance to Animal...");
    Animal.hide();     
    myAnimal.override();

    Animal myAnimal1 = new Animal();
    System.out.println("\nCreate an Animal instance....");
    Animal.hide();     
    myAnimal.override();
}

これで、出力は次のようになります。

Create a Cat instance ...
The hide method in Cat.
The hide method in Cat.
The override method in Cat.  

Cast the Cat instance to Animal...
The hide method in Animal.
The override method in Cat.

Create an Animal instance....
The hide method in Animal.
The override method in Animal.

の場合class methods、ランタイムシステムは、メソッドが呼び出される参照のコンパイル時タイプで定義されたメソッドを呼び出します。

つまり、静的メソッドの呼び出しはコンパイル時にマップされ、実行時に参照が指すインスタンスではなく、宣言された参照の型(この場合は親)に依存します。この例では、のコンパイル時タイプはmyAnimalですAnimal。したがって、ランタイムシステムはで定義されたhideメソッドを呼び出しますAnimal

于 2011-02-20T19:45:26.667 に答える
7

Javaには静的継承があります ニキータの例を適応させる:

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

class C extends B {
    static void test() {
        System.out.print("C");
        B.test();
    }

    public static void main(String[] ignored) {
       C.test();
    }
}

これでコンパイルされ、もちろんCを呼び出すと「CA」が出力されます。次に、クラスBを次のように変更します。

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

Bのみを再コンパイルします(Cは再コンパイルしません)。もう一度Cを呼び出すと、「CB」が出力されます。

ただし、静的メソッドに似たキーワードはありませんsuper。(悪い)正当化は、「スーパークラスの名前はこのクラスの宣言に記述されているため、クラスを変更するには、クラスを再コンパイルする必要がありました。ここでも静的呼び出しを変更してください。」

于 2011-02-20T19:08:55.917 に答える
4

継承の概念全体は、Javaの静的要素には適用されません。たとえば、静的メソッドは別の静的メソッドをオーバーライドできません。
したがって、いいえ、名前で呼び出すか、オブジェクトのインスタンスメソッドにする必要があります。(特にファクトリパターンの1つをチェックすることをお勧めします)。

実例

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

    A a = new B();
    B b = new B();
    a.test();
    b.test();

これは印刷AしてからB。つまり、呼び出されるメソッドは、変数がどのように宣言されているかに依存し、他には何も依存しません。

于 2011-02-20T18:33:29.630 に答える
2

メソッド名とそのパラメーターがわかっていれば、実際にはスーパークラスの静的メソッドを一般的な方法で呼び出すことができます。

public class StaticTest {

    public static void main(String[] args) {
        NewClass.helloWorld();
    }    
}

public class NewClass extends BaseClass {
    public static void helloWorld() {
        try {
            NewClass.class.getSuperclass().getMethod("helloWorld", new Class[] {}).invoke( NewClass.class ,new Object[]{} );
        } catch (Exception e) {
            e.printStackTrace();
        } 

        System.out.println("myVar = " + myVar);
    }
}

public class BaseClass extends BaseBaseClass {
    protected static String myVar;
    public static void helloWorld() {
        System.out.println("Hello from Base");
        myVar = "Good";
    }
}

これは機能するはずであり、サブクラスでは、基本クラスにすべてが設定されています。

出力は次のようになります。

ベースからこんにちは

myVar=良い

于 2016-08-21T07:04:42.230 に答える
1

実装の正式な名前は、メソッド非表示と呼ばれます。静的なinit(Controller controller)メソッドを導入し、インスタンスメソッドを呼び出してオーバーライドを利用することをお勧めします。

public class Controller {
   static void init(Controller controller) {
      controller.init();
   }

   void init() {
      //init stuff
   }
}

public class BaseController extends Controller {

   @override
   void init() {
      super.init();
      //base controller init stuff
   }

}

public class ChildController extends BaseController {
   @override
   void init() {
      super.init();
      //child controller init stuff
   }
}

その後、Controller.init(controllerInstance)を呼び出すことができます。

于 2011-02-20T19:17:30.407 に答える
0

静的メソッドの場合、クラスのインスタンスは必要ないため、スーパーはありません。

于 2011-02-20T18:43:49.893 に答える