如果静态方法不能被覆盖,它在这里工作(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的编译错误,我期待“找不到方法”。 我不明白。

也请按照下面的代码。 这里, ParentdoIt方法现在是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. 如果静态方法不能被覆盖,那么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在一个职位上提出三个问题是不鼓励的,但我仍然愿意回答。

  1. 静态方法不能被覆盖,因为没有必要这样做。 在你的情况下,如果你想覆盖静态方法,你可以调用方法,然后添加你自己的实现,或者你只是创build另一个方法。

  2. 所以,现在你知道静态方法不能被覆盖。 但是你问为什么第三个代码工作? 第三个代码是带有的代码

    public class Child extends Parent {}

对? 虽然静态方法不能被覆盖,但它们可以被inheritance 。 你在做什么是inheritanceParent所以这是完全正确的!

  1. 现在让我告诉你,在你的第一个代码示例中,你隐藏Parent类中的方法,而不是覆盖。 这就是为什么你会得到输出。 final关键字意味着该方法永远不能改变,甚至不能隐藏。 所以这就是为什么。