从静态方法调用超级方法

发布于 2024-10-18 07:17:11 字数 407 浏览 5 评论 0原文

是否可以从子静态方法调用超级静态方法?

我的意思是,以通用的方式,到目前为止,我有以下内容:

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() ,这似乎不起作用。 ..

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 BaseController extends Controller {
    static void init() {
        //init stuff
    }
}

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

}

and it works, but I'd like to do it in a generic way, something like calling super.loadState(), which doesn't seem to work...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

分開簡單 2024-10-25 07:17:11

在Java中,静态方法不能被重写。 此处清楚地解释了原因

因此,它不依赖于它所引用的对象。但相反,它取决于引用的类型。因此,静态方法被称为隐藏另一个静态方法而不是覆盖它。

例如(Cat 是 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");
    }
}

主类:

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.

对于类方法,运行时系统调用引用的编译时类型中定义的方法调用该方法的对象。

换句话说,对静态方法的调用是在编译时映射的,并且取决于引用的声明类型(在本例中为 Parent),而不是运行时引用所指向的实例。在示例中,myAnimal 的编译时类型为 Animal。因此,运行时系统调用Animal中定义的hide方法。

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.

檐上三寸雪 2024-10-25 07:17:11

Java 中有静态继承。改编 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();
    }
}

现在可以编译,当然,调用 C 会打印“CA”。现在我们将类 B 更改为:

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

并仅重新编译 B(而不是 C)。现在再次调用 C,它将打印“CB”。

不过,静态方法没有 super 之类的关键字 - 一个(坏的)理由可能是“超类的名称写在此类的声明中,因此您必须重新编译您的类”尽管如此,为了改变它,所以你也可以在这里改变静态调用。”

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."

り繁华旳梦境 2024-10-25 07:17:11

整个继承概念不适用于 Java 中的静态元素。例如,静态方法不能覆盖另一个静态方法。
所以,不,您必须按名称调用它或使它们成为某个对象的实例方法。 (您可能特别想查看其中一种工厂模式)。

实际示例

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。即,调用的方法取决于变量的声明方式,而不是其他。

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.

不打扰别人 2024-10-25 07:17:11

如果您知道方法名称及其参数,您实际上可以以通用方式调用超类的静态方法。

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

这应该可行,并且在子类中,您可以使用基类中设置的所有内容。

输出应该是:

Hello from Base

myVar = Good

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

赠我空喜 2024-10-25 07:17:11

您的实现的正式名称称为方法隐藏。我建议引入静态 init(Controllercontroller) 方法,并调用实例方法来利用重写。

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)。

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).

傻比既视感 2024-10-25 07:17:11

对于静态方法,不需要类的实例,因此没有 super。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文