为什么在覆盖该方法时调用超类方法? (来自OCA练习测试)

时间:2018-01-30 09:18:49

标签: java static override method-hiding

来自these OCA practice questions (pdf)中的问题三:

abstract class Writer {
   public static void write() {
      System.out.println("Writing...");
   }
}

class Author extends Writer {
   public static void write() {
      System.out.println("Writing book");
   }
}

public class Programmer extends Writer {
   public static void write() {
      System.out.println("Writing code");
   }
   public static void main(String[] args) {
      Writer w = new Programmer();
      w.write();
   }
}

输出为Writing...

我不明白为什么。由于Programmer会覆盖Writer的写入方法,我认为它应该在Programmer而不是Writer中调用该方法。

为什么?

4 个答案:

答案 0 :(得分:4)

你必须在这里理解两点。

对于static成员,没有最重要的概念。它们只是static,并且永远不会根据实例进行更改。

static成员绑定到类而不是实例。所以无论实例是什么,它们都会看到它们被调用和执行的类型。

答案 1 :(得分:1)

参考类型为Writer。您已经调用了一个静态方法,其中不应用覆盖 - 将调用Writer中的方法。

该机制称为method hiding

查看这些案例:

new Programmer().write();             // code  [Programmer]
((Writer)new Author()).write();       // ...   [Writer]

new Author().write();                 // book  [Author]
((Writer)new Programmer()).write();   // ...   [Writer]

new Writer() {{}}.write();            // ...   [Writer]

答案 2 :(得分:1)

众所周知,static方法无法被覆盖。如果我们尝试这样做,那么结果是隐藏方法。在上述情况下,类WriterProgrammer都包含write()方法。

Programmer扩展Writer类并提供自己的write()方法实现时,它只是隐藏了Writer的实现。

现在,在运行时,编译器只检查引用类型(因为它是一个静态方法,编译器不关心为调用方法而创建的对象。请记住,静态方法是类方法)。因此,编译器检查并发现引用w的类型为Writer,它会调用Writer方法的write版本。 如果方法不是static,那么你期望的是输出。

答案 3 :(得分:-1)

自己找到答案。

在Java中没有覆盖静态方法的事情。这就是为什么当从超类引用中调用静态方法时,将调用超类静态方法。

所以

Writing super
sub something

将输出

SubClass sub = new Subclass();
sub.write();

如果要从子类调用静态write()方法。您必须从子类引用它。 E.g:

var input = new OpenCvSharp.Mat(filename, OpenCvSharp.ImreadModes.GrayScale);
var output = input.EmptyClone();
OpenCvSharp.Cv2.Sobel(input, output, OpenCvSharp.MatType.CV_8U, 1, 1);

我了解到这一点的一些消息来源: https://www.geeksforgeeks.org/can-we-overload-or-override-static-methods-in-java/ Why doesn't Java allow overriding of static methods?

相关问题