calling a super method from a static method

后端 未结 6 1417
天涯浪人
天涯浪人 2020-12-05 18:14

Is it possible to call a super static method from child static method?

I mean, in a generic way, so far now I have the following:

public class BaseCo         


        
相关标签:
6条回答
  • 2020-12-05 18:39

    In Java, static methods cannot be overidden. The reason is neatly explained here

    So, it doesn't depend on the object that it is being referenced. But instead, it depends on the type of reference. Hence, static method is said to hide another static method and not override it.

    For example (Cat is a subclass of 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");
        }
    }
    

    Main class:

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

    Now, the output would be as given below

    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.
    

    For class methods, the runtime system invokes the method defined in the compile-time type of the reference on which the method is called.

    In other words, call to static methods are mapped at the compile time and depends on the declared type of the reference (Parent in this case) and not the instance the reference points at runtime. In the example, the compile-time type of myAnimal is Animal. Thus, the runtime system invokes the hide method defined in Animal.

    0 讨论(0)
  • 2020-12-05 18:42

    For static methods there is no instance of a class needed, so there is no super.

    0 讨论(0)
  • 2020-12-05 18:51

    The whole inheritance concept isn't applied to static elements in Java. E.g., static method can't override another static method.
    So, no, you'll have to call it by name or make them instance methods of some object. (You might want to check out one of factory patterns in particular).

    A practical example

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

    This prints A and then B. I.e., invoked method depends on how variable is declared and nothing else.

    0 讨论(0)
  • 2020-12-05 18:53

    The official name of your implementation is called method hiding. I would suggest introducing a static init(Controller controller) method, and calling an instance method to take advantage of 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
       }
    }
    

    You can then call Controller.init(controllerInstance).

    0 讨论(0)
  • 2020-12-05 18:59

    There is static inheritance in Java. Adapting the example from 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();
        }
    }
    

    This now compiles, and invoking C prints "CA", of course. Now we change class B to this:

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

    and recompile only B (not C). Now invoking C again, it would print "CB".

    There is no super like keyword for static methods, though - a (bad) justification may be that "The name of the super class is written in the declaration of this class, so you had to recompile your class nevertheless for changing it, so you could change the static calls here, too."

    0 讨论(0)
  • 2020-12-05 19:01

    You can actually call the static method of a superclass in a generic way, given that you know the method name and its parameters.

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

    This should work and in the subclass you have everything set in the base class available.

    The output should be:

    Hello from Base

    myVar = Good

    0 讨论(0)
提交回复
热议问题