如果无法覆盖静态方法,那么它在这里工作(For Java)? [英] If static methods can't be overridden, how its working here (For Java)?

查看:100
本文介绍了如果无法覆盖静态方法,那么它在这里工作(For Java)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的理解是静态变量和静态方法属于类,而不是类对象。因此静态方法的覆盖在Java中不起作用,因为覆盖我们需要创建一个类的实例。但是我今天尝试的东西与我对Java的知识相矛盾。

My understanding was that static variables and static methods are of a class, not of the class objects. So an Override of a static method won't work in Java, as for overriding we need an instance of a class to be created. But I was trying something today that contradicted my knowledge of Java.

请遵循以下代码:

class Parent{
   public static void doIt(){
      System.out.println("In static method 'doit' of class Parent ");
   }
}

class Child extends Parent{    
   public static void doIt(){
      System.out.println("In static method 'doit' of class Child ");
   }
}

public class StaticPractise{
   public static void main(String[] args){
      Parent.doIt();
      Child.doIt();
   }    
}

上述实现的输出是:

D:\Rahul Shivsharan\MyPractise\JAVA>java StaticPractise
In static method 'doit' of class Parent
In static method 'doit' of class Child

从这个输出中我可以理解尽管类扩展 Parent 类, doit 方法是每个班级的个人,因为他们是静态。所以不允许覆盖它们。

From this output I can understand that though the Child class extends the Parent class, the doit methods are individual to each class as they are static. So no overriding of them is allowed.

现在请按照下面的代码,其中 @Override 被添加到孩子的 doIt 方法:

Now please follow the below code, where @Override is added to the child's doIt method:

class Parent{
   public static void doIt(){
      System.out.println("In static method 'doit' of class Parent ");
   }
}

class Child extends Parent{    
   @Override // Adding this annotation here
   public static void doIt(){
      System.out.println("In static method 'doit' of class Child ");
   }
}

public class StaticPractise{
   public static void main(String[] args){
      Parent.doIt();
      Child.doIt();
   }    
}

上述代码的输出给出了编译错误如下:

The output of the above code gives a compilation error as follows:

D:\Rahul Shivsharan\MyPractise\JAVA>javac StaticPractise.java
StaticPractise.java:31: error: method does not override or implement a method from a supertype
    @Override
    ^
1 error

这里明确说明注释覆盖无法应用于 static 方法,因为它们没有被覆盖。

Here it clearly says that the annotation Override can't be applied in static methods as they are not getting overridden.

现在请按照下面的代码,其中 Child 没有 doIt 方法:

Now please follow the below code, where Child has no doIt method:

class Parent{
   public static void doIt(){
      System.out.println("In static method 'doit' of class Parent ");
   }
}

class Child extends Parent{ /* no doIt method */ }

public class StaticPractise{
   public static void main(String[] args){
      Parent.doIt();
      Child.doIt();
   }    
}

输出为:

D:\Rahul Shivsharan\MyPractise\JAVA>java StaticPractise
In static method 'doit' of class Parent
In static method 'doit' of class Parent

为什么上面的代码编译并运行?我期待类Child的方法 doit 的编译错误,我期待找不到方法。我不明白。

Why does the above code compile and run? I was expecting a compilation error for method doit for class Child, and I was expecting "Method not found". I don't understand.

另请注意以下代码。这里, Parent 中的 doIt 方法现在是 final

Also please follow the below code. Here, the doIt method in Parent is now final.

class Parent{
   public static final void doIt(){ // now final
      System.out.println("In static method 'doit' of class Parent ");
   }
}

class Child extends Parent{
   public static void doIt(){
      System.out.println("In static method 'doit' of class Parent ");
   }
}

public class StaticPractise{
   public static void main(String[] args){
      Parent.doIt();
      Child.doIt();
   }    
}

运行上述代码后的输出如下:

The output after running the above code is as follows:

D:\Rahul Shivsharan\MyPractise\JAVA>javac StaticPractise.java
StaticPractise.java:30: error: doIt() in Child cannot override doIt() in Parent
    public static void doIt(){
                       ^
  overridden method is static,final
 1 error

 D:\Rahul Shivsharan\MyPractise\JAVA>

我所期待的是上面的代码应该可以正常工作,因为 doit 方法在每个类中都是静态的,所以即使 final 关键字也不应该出现任何编译错误,因为方法是 static

What I was expecting was that the above code should work fine as the doit methods are static in each class, so even a final keyword should not make any compilation error as the method is static.

请向我解释一下方法覆盖如何在Java中的静态类中起作用。

Please explain to me how method overriding works in static classes in Java.


  1. 可以覆盖静态方法吗?如果是,那么如何注释 @Override 会失败?

  2. 如果无法覆盖静态方法,那我的第三个代码怎么样?块运行正常吗?

  3. 如果无法覆盖静态方法,那么 final 关键字怎么会产生影响呢?

  1. Can static methods be overridden? If yes, then how come annotating @Override fails?
  2. If static methods can't be overridden, then how come my 3rd code block runs fine?
  3. If static methods can't be overridden, then how come the final keyword makes a difference?


推荐答案

首先,这里涉及不同的机制:覆盖和阴影(也称为隐藏)

First of all there are different mechanisms involved here: Overriding and Shadowing (also called hiding).

1)
静态方法无法覆盖,因为它们附加到它们所定义的类中。但是,您可以隐藏/隐藏静态方法,就像使用 Parent / Child class。这意味着,该方法在 Child 类中被替换,但仍然可以从 Parent 类中获得。

1) Static methods cannot be overriden as they are attached to the class they are defined in. However, you can shadow/hide a static method as you are doing with your Parent/Child class. This means, the method gets replaced in the Child class but is still available from the Parent class.

当您从这些类的实例调用静态方法时(而不是使用),您会更明显地覆盖Class.staticMethod() invocation)。

It gets more obvious that you are not overriding when you are calling the static methods from instances of those classes (and not using the Class.staticMethod() invocation).

Parent parent = new Parent();
Child child1 = new Child();
Parent child2 = new Child();

parent.StaticMethod();
child1.StaticMethod();
child2.StaticMethod();

输出

Static method from Parent
Static method from Child
Static method from Parent

答案是派遣方法。你可以在这里获取源代码

The answer is the dispatch of the methods. You can grab the source code here

2)
dispatch在 Parent 类中找到该方法。没有动态分派,因为运行时类型用于查找方法句柄。它使用编译时类型。 提醒:从实例调用静态方法被认为是不好的做法,因为上面的事情可能会发生并容易被忽视。

2) The dispatch finds the method on the Parent class. There is no dynamic dispatch as that the runtime type is used to find the method handle. It uses the compile time type. Remind: Calling static methods from instances is considered bad practice since things like above can happen and are easy to be overlooked.

3)
使用 final ,您声明该方法无法被覆盖,也不能被遮蔽/隐藏。

3) With finalyou declare that the method cannot be overridden neither shadowed/hidden.

这篇关于如果无法覆盖静态方法,那么它在这里工作(For Java)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆