当前位置: 首页 > 知识库问答 >
问题:

为什么在重写超类方法时调用该方法?(来自亚奥理事会实践测试)[副本]

欧阳成弘
2023-03-14

来自OCA实践问题(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();
   }
}

输出是写入

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

为什么?


共有3个答案

苗学民
2023-03-14

正如我们所知,静态方法不能被重写。如果我们试图这么做,结果却是方法隐藏。在上述情况下,类-WriterProgrammer都包含write()方法。

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

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

鲁博雅
2023-03-14

引用的类型是Writer。您调用了一个未应用覆盖的静态方法——将调用编写器中的方法

这种机制称为方法隐藏。

看看这些案例:

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

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

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

殳宸
2023-03-14

你必须理解两点。

静态成员的情况下,没有压倒一切的概念。它们只是静态,并且不会根据实例进行更改。

静态成员绑定到类而不是实例。因此,无论实例是什么,它们都会查看调用和执行的类型。

 类似资料:
  • 这是我的密码 结果为上述结果之一。从调用仍然调用子类的,即使从词汇上讲,meth调用在超类内部!那么,当是私有的时候,为什么会有不同的行为呢? ___________edit____________ 代码是这样的吗 O/P将是 因此,即使超级类中的正在调用,但实际上子类的正在被调用。所以,方法调用不是词法意义上的!也就是说,即使看起来将调用超级类的meth,实际上它的子类的becoz子类实例首先调

  • 我用java编写Rational类来做基本的数学运算,我想覆盖Number类和Comparable接口的方法。我这样做是为了双倍的价值 正如我们所知,BigInteger类也扩展了数字类,所以我对在doubleValue中调用哪个方法感到困惑,因为我已经覆盖了doubleValue

  • 当我们不知道任何给定对象的finalize()方法何时可以运行时,我们需要在java中重写finalize()方法的哪里?我们可以在finalize()中关闭什么类型的资源?GC调用finalize()方法的最佳机会是什么?

  • 我有下面的类,我测试了method1,并模拟了method2和method3。我只测试这样的用例:*如果method2调用是OK,那么==>OK*如果method2抛出NotFoundException,method3返回OK==>OK*如果method2抛出NotFoundException,method3抛出ServiceException==>ServiceException确实抛出了 为了

  • 我有一个基类,它定义了类方法,用于返回用于构建服务url的各种信息。基类还定义了一个用于构建该url的实例方法。我希望基类有这个方法的默认实现,这样当我需要url不同时,我只需要在子类中重写它。我如何让这个基方法调用重写的类方法来使用子类中的类方法构建url?下面是我现在的代码,但它不起作用: 基类方法: op ationId、operationVersion和方法类型是在子类中实现的类方法,但是

  • 我试图在下面的类中进行测试,但得到了“org.mockito.exceptions.base.MockitoException:只有void方法才能执行任何操作()!”当我试图嘲笑时,我得到了nullpointerException。 笔试= 模拟测试 @RunAnd(MockitoJUnitRunner.class) 类PsqlConfigurationTest{ }