【问题标题】:Java: make a function not virtual - call parent method on parent reference [duplicate]Java:使函数不是虚拟的-在父引用上调用父方法[重复]
【发布时间】:2017-12-11 01:34:07
【问题描述】:

我想这个问题以前有人问过,但没有立即找到答案。

说,不知何故,Pet 引用被分配了一个 Dog 对象:

Pet pet = new Dog();

如果我写

pet.attackInvader();

调用子类(Dog)的方法是因为 Java 中的所有函数都是虚函数。

是否可以改为调用PetattackInvader()

(我知道我可以编辑Dog 的方法来调用super,但是,在这种情况下,假设我不能更改Dog 的实现。)

【问题讨论】:

  • 我知道以前有人问过,我会搜索它...
  • DM:好的,谢谢。
  • AFAIK,这是不可能的(没有严重的反思)。
  • @AndyTurner 我不同意这是该特定问题的重复,即使它几乎可以肯定是重复的。如果您无法修改 Dogsuper() 将无济于事。
  • java.lang.invoke.MethodHandle 提供了一个脆弱的解决方法。您基本上使用 { Pet.class, Lookup.PRIVATE } 反射调用私有 MethodHandles.Lookup(Class<?>, int) 构造函数,然后在查找对象上调用 findSpecial 以获取描述非覆盖方法的 MethodHandle,最后通过句柄调用它,在您的 pet (Dog) 实例上。我相信至少有一个答案可以证明这种方法,但现在找不到。

标签: java polymorphism


【解决方案1】:

如果不覆盖Dog 中的方法并且不将实例化对象从Dog 更改为Pet,这是不可能的,因为多态以这种方式工作:
在运行时调用的方法始终是运行时对象的方法。
现在作为替代方案,您可以在 Dog 中提供一个方法,将其转换为 Pet 实例:

  public Pet toPet(){
      return new Pet(...);
 }

然后调用attackInvader()

myDog.toPet().attackInvader();

或者通过在Dog 中创建一个提供此特定行为的新方法:

  public void attackInvaderPet(){
      super.attackInvader();
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    • 2016-04-05
    • 2017-08-13
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2018-11-05
    相关资源
    最近更新 更多