l'appel d'une méthode super partir d'une méthode statique

Est-il possible d'appeler une super méthode statique de l'enfant méthode statique?

je veux dire, de façon générique, jusqu'à maintenant j'ai la suivante:

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

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

}

et ça marche, mais j'aimerais le faire d'une manière générique, quelque chose comme appeler super.loadState(), qui ne semble pas fonctionner...

21
demandé sur Lightness Races in Orbit 2011-02-20 21:30:45

6 réponses

en Java, les méthodes statiques ne peuvent pas être exagérées. La raison est bien expliquée ici

ainsi, cela ne dépend pas de l'objet auquel il est référencé. Mais au lieu de cela, il dépend du type de référence. Par conséquent, la méthode statique est dit pour cacher une autre méthode statique et ne pas l'annuler.

par exemple (le chat est une sous-classe de L'Animal):

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");
    }
}

classe Principale:

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();
}

Maintenant, la sortie serait comme indiqué ci-dessous

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.

pour class methods , le système runtime invoque la méthode définie dans le type de compilation de la référence sur laquelle la méthode est appelée.

en d'autres termes, l'appel aux méthodes statiques est mappé au moment de la compilation et dépend du type déclaré de la référence (Parent en ce cas) et non l'instance les points de référence à l'exécution. Dans l'exemple, le type de compilation myAnimal est Animal . Ainsi, le système runtime invoque la méthode hide définie dans Animal .

15
répondu Javascript is GOD 2018-01-25 14:17:27

Il y est héritage statique en Java. Adaptation de L'exemple de Nikita:

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();
    }
}

cela compile maintenant, et en invoquant c imprime "CA", bien sûr. Maintenant, nous changeons la Classe B comme suit:

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

et recompiler uniquement B (et non C). En invoquant à nouveau C, il imprimerait "CB".

il n'y a pas de super comme mot clé pour les méthodes statiques, bien que-a (mauvais) la justification peut être que "Le nom de la super-classe est écrit dans la déclaration de cette classe, de sorte que vous avez eu à recompiler votre classe néanmoins pour le changer, de sorte que vous pouvez changer la statique appelle ici, trop."

6
répondu Paŭlo Ebermann 2011-02-20 19:08:55

le concept d'héritage entier n'est pas appliqué aux éléments statiques en Java. Par exemple, la méthode statique ne peut pas remplacer une autre méthode statique.

Donc, non, vous devrez l'appeler par son nom, ni de leur faire des méthodes d'instance d'un objet. (Vous pourriez vouloir vérifier l'un des modèles d'usine en particulier).

un exemple pratique

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 imprime A et puis B . C'est-à-dire: la méthode invoquée dépend de comment variable est déclarée et rien d'autre.

4
répondu Nikita Rybak 2011-02-20 18:33:29

vous pouvez en fait appeler la méthode statique d'une superclasse de manière générique, étant donné que vous connaissez le nom de la méthode et ses paramètres.

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";
    }
}

Cela devrait fonctionner et dans la sous-classe, vous avez tout mis dans la classe de base disponibles.

la sortie doit être:

Bonjour de Base

myVar = Bonne

2
répondu StefaX 2016-08-21 07:04:42

le nom officiel de votre implémentation est appelé méthode de dissimulation . Je suggérerais d'introduire une méthode statique init(Controller controller), et d'appeler une méthode d'instance pour tirer avantage de overriding.

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
   }
}

vous pouvez alors appeler le contrôleur.init (controllerInstance).

1
répondu BBb 2011-02-20 19:17:30

Pour les méthodes statiques il n'existe aucune instance d'une classe nécessaire, donc il n'est pas super.

0
répondu James 2011-02-20 18:43:49