我的理解是静态变量和静态方法属于一个类,而不是属于类对象。因此,静态方法的 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
方法对于每个类都是独立的,因为它们是静态
。所以不允许覆盖它们。
现在请按照下面的代码,其中 @Override
被添加到 child 的 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
为什么上面的代码可以编译运行?我期待 Child 类的方法 doit
出现编译错误,并且期待“找不到方法”。我不明白。
另外,请按照以下代码。在这里,Parent
中的 doIt
方法现在是 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 中的静态类中是如何工作的。
- 可以覆盖静态方法吗?如果是,那么为什么注释
@Override
会失败? - 如果静态方法不能被覆盖,那我的第三个代码块怎么运行得很好?
- 如果静态方法不能被覆盖,那么
final
关键字有何不同?
最佳答案
首先这里涉及到不同的机制:Overriding and Shadowing (also called hiding) .
1)
静态方法不能被覆盖,因为它们附加到定义它们的类。但是,您可以像使用 Parent
一样隐藏/隐藏静态方法。/Child
类(class)。这意味着,该方法在 Child
中被替换。类,但仍可从 Parent
获得类。
更明显的是,当您从这些类的实例调用静态方法(而不是使用 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
答案是方法的分派(dispatch)。你可以捕获source code here
2)
dispatch 在 Parent
上找到方法类(class)。没有动态分派(dispatch),因为运行时类型用于查找方法句柄。它使用编译时类型。 提醒:从实例调用静态方法被认为是不好的做法,因为上述情况可能会发生并且很容易被忽视。
3)
与 final
您声明该方法不能被覆盖,也不能被隐藏/隐藏。
关于java - 如果静态方法不能被覆盖,它如何在这里工作(对于 Java)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32112692/