来自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
中调用该方法。
为什么?
答案 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
方法无法被覆盖。如果我们尝试这样做,那么结果是隐藏方法。在上述情况下,类Writer
和Programmer
都包含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?