如果无法覆盖静态方法,那么它的工作原理如何(For Java)?

Rah*_*ran 38 java overriding

我的理解是静态变量和静态方法属于类,而不是类对象.因此Override,静态方法在Java中不起作用,因为重写我们需要创建一个类的实例.但我今天尝试的东西与我的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();
   }    
}
Run Code Online (Sandbox Code Playgroud)

上述实现的输出是:

D:\Rahul Shivsharan\MyPractise\JAVA>java StaticPractise
In static method 'doit' of class Parent
In static method 'doit' of class Child
Run Code Online (Sandbox Code Playgroud)

从这个输出中我可以理解,尽管Child类扩展了Parent类,但这些doit方法对于每个类都是个体的static.所以不允许覆盖它们.

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

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();
   }    
}
Run Code Online (Sandbox Code Playgroud)

上面代码的输出给出了一个编译错误,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

这里明确指出,注释Override不能应用于static方法,因为它们不会被覆盖.

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

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();
   }    
}
Run Code Online (Sandbox Code Playgroud)

输出是:

D:\Rahul Shivsharan\MyPractise\JAVA>java StaticPractise
In static method 'doit' of class Parent
In static method 'doit' of class Parent
Run Code Online (Sandbox Code Playgroud)

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

另请注意以下代码.这里,doIt方法Parent是现在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();
   }    
}
Run Code Online (Sandbox Code Playgroud)

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

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>
Run Code Online (Sandbox Code Playgroud)

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

请解释一下如何在Java中的静态类中使用方法重写.

  1. 可以覆盖静态方法吗?如果是,那么注释如何@Override失败?
  2. 如果无法覆盖静态方法,那么为什么我的第3代码块运行良好呢?
  3. 如果无法覆盖静态方法,那么final关键字如何产生影响呢?

lsc*_*tze 41

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

1)静态方法不能被覆盖,因为它们被附加到它们所定义的类中.但是,您可以像对待/ 类一样隐藏/隐藏静态方法.这意味着,该方法在类中被替换,但仍然可以从类中获得.ParentChildChildParent

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

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

parent.StaticMethod();
child1.StaticMethod();
child2.StaticMethod();
Run Code Online (Sandbox Code Playgroud)

输出是

Static method from Parent
Static method from Child
Static method from Parent
Run Code Online (Sandbox Code Playgroud)

答案是派遣方法.您可以在此处获取源代码

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

3)final声明无法覆盖该方法既不会被遮蔽/隐藏.

  • 还应该注意的是,编译器正在添加"overridden method is static,final"的消息.应该读取阴影/隐藏. (3认同)

Jor*_*lla 6

你混淆了压倒一切的隐藏

  • 它让我觉得"混乱"也很突出.:/ (10认同)