如何覆盖调用超类'超类方法的方法?

时间:2009-04-07 16:43:11

标签: java oop class-design

我的一部分认为这不应该是可能的(即使它是),但无论如何我都会问。

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

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层次结构的关键元素(换句话说,我不是在寻找“make {{1} } Child“的子类。

4 个答案:

答案 0 :(得分:10)

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

这似乎是你在这里继承只是为了重用代码,而这不是子类化的想法。

也许您应该有一个帮助成员来完成您需要的一些任务,而不是子类化,并且“Child”和“Parent”类都扩展为“祖父母”。

你需要问自己的主要问题是:“孩子真的是父母,祖父母或者neiter的后裔吗?”换句话说,对于每个Child的实例,,我可以说它是父母吗?

如果答案是否定的,那么你就是错误地继承子类:继承应该意味着什么,而不仅仅是代码重用(即福特它也是汽车 ,而不仅仅是“福特”使用“汽车”方法。)

答案 1 :(得分:3)

假设我无法触及Parent或Grandparent中的代码并假设我不是,正如Seb建议的那样(并且Steve显然同意)只是完全滥用继承:

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

这是一个丑陋的解决方案,并且,根据访问的状态信息的数量,可能会像地狱一样脆弱。但是如果祖父是可靠的稳定和/或myMethod()是相当独立的,它可以工作。一如既往,魔鬼在细节中。

我绝对同意Seb的说法,这是重用,而不是继承。但是,嘿。重复使用往往是一件好事。

答案 2 :(得分:2)

不可能。

我会在祖父母中创建一个final辅助方法。并且让这个方法(被覆盖)调用那个帮助器。

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();
   }
}

答案 3 :(得分:2)

您是否拥有父类的控制权?

如果是这样,你可以向在祖父母上调用myMethod的Parent添加一个方法(myNewMethod),并从Child调用myNewMethod吗?

(我不是Java人员,所以不知道你是否只能通过子类中该方法的覆盖来调用超类中的方法)

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();
   }
}