如果静态方法不能被覆盖,它在这里工作(For Java)?
我的理解是,静态variables和静态方法是一个类,而不是类对象。 所以一个静态方法的重载将不能在Java中工作,至于重写,我们需要创build一个类的实例。 但是我今天在尝试一些与我对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
为什么上面的代码编译和运行? 我期待一个类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
关键字如何起作用?
首先,这里涉及不同的机制: 覆盖和遮蔽(也称为隐藏) 。
1)静态方法不能被重写,因为它们被附加到它们所定义的类中。但是,您可以像使用Parent
/ Child
类一样遮蔽/隐藏静态方法。 这意味着,该方法在Child
类中被replace,但仍然可以从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
答案是调度的方法。 你可以在这里获取源代码
2)派遣在Parent
类上find方法。 由于运行时types用于查找方法句柄,因此不存在dynamic分派。 它使用编译时间types。 提醒 :从实例中调用静态方法被认为是不好的做法,因为像上面这样的事情可能发生,很容易被忽视。
3) final
你声明,该方法不能被覆盖既不被遮蔽也不被隐藏。
你在隐瞒 凌辱 ,是令人困惑的
尽pipe在一个职位上提出三个问题是不鼓励的,但我仍然愿意回答。
-
静态方法不能被覆盖,因为没有必要这样做。 在你的情况下,如果你想覆盖静态方法,你可以调用方法,然后添加你自己的实现,或者你只是创build另一个方法。
-
所以,现在你知道静态方法不能被覆盖。 但是你问为什么第三个代码工作? 第三个代码是带有的代码
public class Child extends Parent {}
对? 虽然静态方法不能被覆盖,但它们可以被inheritance 。 你在做什么是inheritanceParent
所以这是完全正确的!
- 现在让我告诉你,在你的第一个代码示例中,你隐藏了
Parent
类中的方法,而不是覆盖。 这就是为什么你会得到输出。final
关键字意味着该方法永远不能改变,甚至不能隐藏。 所以这就是为什么。