如果静态方法不能被覆盖,那么它在这里如何工作(对于Java)?

拉胡尔·希夫沙兰(Rahul Shivsharan):

我的理解是静态变量和静态方法是类的,而不是类对象的。因此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();
   }    
}

以上实现的输出为:

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

从该输出中,我可以理解,尽管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();
   }    
}

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

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

在这里,它清楚地表明注释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();
   }    
}

输出为:

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

为什么上面的代码会编译并运行?我期待doitChild类的方法发生编译错误,并且期待“找不到方法”。我不明白

另外,请遵循以下代码。在这里,doItin中方法Parent是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();
   }    
}

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

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

请向我解释方法重写在Java的静态类中如何工作。

  1. 可以重写静态方法吗?如果是,那么注释如何@Override失败?
  2. 如果不能重写静态方法,那么我的第3个代码块如何运行良好?
  3. 如果静态方法不能被覆盖,那么final关键字又如何发挥作用呢?
lschuetze:

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

1)静态方法不能被覆盖,因为它们被附加到定义它们的类中。但是,您可以像对/ 那样对静态方法进行阴影/隐藏这意味着该方法将在类中被替换,但仍可从该类中使用。ParentChildChildParent

显而易见,从那些类的实例调用静态方法(而不使用调用),您没有覆盖Class.staticMethod()

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

答案是方法的调度。您可以在此处获取源代码

2)调度程序在Parent上找到方法没有动态分配,因为运行时类型用于查找方法句柄。它使用编译时间类型。提醒:从实例调用静态方法被认为是不好的做法,因为上述情况可能发生,并且容易被忽略。

3)通过final声明,该方法不能被覆盖/隐藏/隐藏。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章