关于java:如何覆盖调用超类’超类方法的方法?

How to override method to invoke superclass' superclass method?

本问题已经有最佳答案,请猛点这里访问。

我的一部分人认为这不可能(即使可能),但我还是会问。

鉴于以下类层次结构(GrandparentParent来自第三方,因此不在我的控制之下),我如何在Child中重写myMethod()以便它绕过Parent中被重写的实现并调用Grandparent中的实现?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Grandparent {
   public void myMethod() {
      // do stuff
   }
}

class Parent extends Grandparent {
   @Override public void myMethod() {
      super.myMethod();
      // do something else
   }
}

class Child extends Parent {
   @Override public void myMethod() {
      // ??? I want to *only* do what Grandparent did here
   }
}

假设Parent类提供了许多其他有用的行为,并且是Child层次结构的一个关键元素(换句话说,我不希望"使Child成为Grandparent的子类")。


继承背后的思想是,每个类都定义了它们需要的方法,因此您不需要检查任何代码。

似乎您在这里进行子类化只是为了重用代码,而这不是子类化的概念。

也许您应该有一个助手成员来完成一些您需要的任务,而不是子类化,并且让"child"和"parent"类同时扩展"graphrent"。

你需要问自己的主要问题是:"孩子真的是父母、祖父母或邻居的后代吗?"换句话说,对于孩子的每一个例子,我能说它是父母吗?

如果答案是否定的,那么你的子类化就错了:继承应该意味着某种东西,而不仅仅是代码重用(即福特也是一辆汽车,而不仅仅是"福特"使用"汽车"方法)。


假设我无法接触到父母或祖父母的密码,假设我没有,正如SEB所建议的(史蒂夫显然同意的),只是完全滥用了继承权:

我将创建一个祖父对象的本地实例(或者一个扩展祖父的本地类,如果它是抽象的),并直接访问它对mymethod()的解释。当然,根据MyMethod()应该读取和/或操作多少状态信息,所涉及的工作量可以是从"简单"到"痛苦"的任何内容。

这是一个丑陋的解决方案,而且,取决于访问了多少状态信息,可能会像地狱一样脆弱。但如果祖父是可靠稳定的和/或mymethod()是相当独立的,它就可以工作。魔鬼总是在细节上。

我完全同意SEB的观点,这是重复使用,而不是继承。但是,嘿。重复使用通常是一件好事。


你能控制父类吗?

如果是这样,可以向对祖辈调用MyMethod的父级添加方法(MyNewMethod)并从子级调用MyNewMethod吗?

(我不是Java人,所以不知道您是否只能从子类中的方法中调用超类中的方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Grandparent {
   public void myMethod() {
      myHelperMethod();
   }
}

class Parent extends Grandparent {
   @Override public void myMethod() {
      super.myMethod();
      // do something else
   }
   public final void myNewMethod() {
      super.myMethod();
   }
}

class Child extends Parent {
   @Override public void myMethod() {
      // ??? I want to *only* do what Grandparent did here
      myNewMethod();
   }
}


不可能。

我将在祖父母中创建一个final助手方法。并让这个方法(被重写)调用那个助手。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Grandparent {
   public final void myHelperMethod() {
      // do stuff
   }
   public void myMethod() {
      myHelperMethod();
   }
}

class Parent extends Grandparent {
   @Override public void myMethod() {
      super.myMethod();
      // do something else
   }
}

class Child extends Parent {
   @Override public void myMethod() {
      // ??? I want to *only* do what Grandparent did here
      myHelperMethod();
   }
}