【发布时间】:2015-03-21 06:16:12
【问题描述】:
我有一个经典的钻石继承问题
A
/ \
B C
\ /
D
都是接口,我有
AImpl(A)
| \
| \
BImpl(B) CImpl(C)
| \
| \
DImpl(B,C) \
| F(C)
|
E(B,C)
其中类E 实现了接口B 和C,但F 只实现了接口C。
由于缺少多重继承,我目前在DImpl 和CImpl 中有重复的功能。
我刚刚修复了CImpl 中的一个错误,但忘记为DImpl 做同样的事情。显然,记住始终将代码从 CImpl 复制到 DImpl,反之亦然,因为代码库不断增长,因此不太可持续。尽管不允许多重继承,是否有任何既定的最佳实践可以将两者的共享代码放在一个地方?
编辑 -- 多重继承的解决方案是让DImpl继承CImpl.cFunction(),而不是将DImpl.cFunction重新定义为CImpl.cFunction的副本
EDIT 2 -- 示例代码:
public interface Animal {
public void eat();
}
public interface FlyingAnimal extends Animal {
public void fly();
}
public interface RunningAnimal extends Animal {
public void run();
}
public interface Monster extends FlyingAnimal, RunningAnimal {
public void roar();
}
public class AnimalImpl implements Animal {
@Override
public void eat() {
...
}
}
public class FlyingAnimalImpl extends AnimalImpl implements FlyingAnimal {
@Override
public void fly() {
...
}
}
public class RunningAnimalImpl extends AnimalImpl implements RunningAnimal {
@Override
public void run() {
...
}
}
public class MonsterImpl extends FlyingAnimalImpl implements Monster {
@Override
public void run() {
...
}
@Override
public void roar() {
...
}
}
public class ScaryMonster extends MonsterImpl implements Monster {
public void sneakAround() {
...
}
}
public class Human extends RunningAnimalImpl implements RunningAnimal {
public void scream() {
...
}
}
现在,如果我在 RunningAnimalImpl.run() 中发现错误并修复它,我必须记住将修复复制到 MonsterImpl.run()。
【问题讨论】:
-
什么是 A、B、C 和 D?
-
你确定你的层次结构正确吗?用这些通用名称是不可能的。如果有多重继承,你的解决方案是什么?
标签: java multiple-inheritance diamond-problem