4

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

给定以下类层次结构(Grandparent并且Parent来自第 3 方,因此不受我的控制),我将如何覆盖myMethod()inChild以绕过覆盖的实现Parent并调用 in 中的实现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的层次结构的关键元素(换句话说,我不是在寻找“创建Child一个子类Grandparent”。

4

4 回答 4

10

继承背后的想法是,每个类都根据需要定义其方法,因此您无需检查任何代码。

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

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

您需要问自己的主要问题是:“Child 真的是 Parent、Grandparent 或 neiter 的后代吗?” 换句话说,对于 Child 的每个实例,我可以说它是 Parent吗?

如果答案是否定的,那么您的子类化是错误的:继承应该意味着某些东西,而不仅仅是代码重用(即Ford IS ALSO a Car,而不仅仅是“Ford”使用“Car”方法)。

于 2009-04-07T17:07:10.573 回答
3

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

我会创建一个 Grandfather 对象的本地实例(或者一个扩展 Grandfather 的本地类,如果它是抽象的)并直接访问它对 myMethod() 的解释。当然,根据 myMethod() 应该读取和/或操作多少状态信息,所涉及的工作量可能从“容易”到“难以忍受”。

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

我绝对同意 Seb 的观点,即这是重用,而不是继承。但是,嘿。重复使用通常是一件好事。

于 2009-04-07T17:53:50.570 回答
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();
   }
}
于 2009-04-07T16:44:39.677 回答
2

您可以控制 Parent 类吗?

如果是这样,您是否可以向父级添加一个方法(myNewMethod),该方法在祖父级上调用 myMethod,并从子级调用 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();
   }
}
于 2009-04-07T16:58:09.987 回答