Oop 删除多重继承
我正在研究多重继承,我读到它被认为是糟糕的设计 我创建了一个多继承有用的示例,但我没有找到重写它以删除多继承的方法。Oop 删除多重继承,oop,inheritance,multiple-inheritance,code-reuse,Oop,Inheritance,Multiple Inheritance,Code Reuse,我正在研究多重继承,我读到它被认为是糟糕的设计 我创建了一个多继承有用的示例,但我没有找到重写它以删除多继承的方法。 此外,许多语言不支持多重继承,因此需要一种新的设计 “Animal”类实现了所有动物都会做的许多事情。 “AquaticAnimal”类实现了关于水的所有功能。 “TerrestrialAnimal”类实现了关于陆地上动物的一切 “两栖”类是为那些能做“水生动物”和“陆地动物”所能做的一切的动物而设立的。 应用程序需要在类中使用“两栖”动物:动物园、宝瓶座、平原和两栖种族 尽管存
此外,许多语言不支持多重继承,因此需要一种新的设计 “Animal”类实现了所有动物都会做的许多事情。
“AquaticAnimal”类实现了关于水的所有功能。
“TerrestrialAnimal”类实现了关于陆地上动物的一切 “两栖”类是为那些能做“水生动物”和“陆地动物”所能做的一切的动物而设立的。
应用程序需要在类中使用“两栖”动物:动物园、宝瓶座、平原和两栖种族 尽管存在虚拟继承,但菱形问题仍然存在,因为调用两栖类.eat()将调用Animal.eat()两次,这将导致状态不一致 它不是一种真正的编程语言,但它类似于Java/C++
class Animal{
private:
Place birthplace;
String name;
List likesToEat;
Stomach stomach;
public:
virtual void growl(){ ... }
virtual int eat(Food food){
... test if likes
... many operations
chew()
...
stomach.fill(food);
}
}
class FlyingAnimal extends Animal {
private:
Wings wings;
public:
void fly(){ ... wings.move(); ... }
}
class AquaticAnimal extends Animal{
private:
Flipper flipper;
public:
void swim(){ ... flipper.move(); ... }
int eat(Food food){
int x = Animal.eat(food);
... use x
flipper.nourish(food);
}
}
class TerrestrialAnimal extends Animal{
private:
Legs legs;
public:
void run(){ ... legs.move(); ... }
int eat(Food food){
int x = Animal.eat(food);
... use x
legs.nourish(food);
}
}
class Amphibious extends AquaticAnimal, TerrestrialAnimal{
public:
int eat(Food food){
AquaticAnimal.eat(food);
TerrestrialAnimal.eat(food);
//PROBLEM: Animal.eat() will be called twice.
}
}
//------------------------------------------
class Zoo {
public:
void add/remove(Animal a);
void feed(Animal a);
void show(Animal a);
}
class Aquarius {
public:
void add/remove(AquaticAnimal a);
}
class Plains {
public:
void add/remove(TerrestrialAnimal a);
}
class HighPeaks {
public:
void add/remove(FlyingAnimal a);
}
class AmphibiousRace {
public:
void add/remove(Amphibious a);
void enterIntoLake(Amphibious a);
void exitFromLake(Amphibious a);
}
如果是腿和鳍状肢区分了水生动物和陆生动物,那么说两栖动物是从这两种动物中继承来的真的有效吗?不是很多动物都有腿和鳍状肢 无论哪种方式,您都可以使用更多的合成方法,将所需的片段传递到类中:
class Animal{
private:
Place birthplace;
String name;
List likesToEat;
Stomach stomach;
public:
virtual IEnumerable<Movement > Movements { get; }
virtual IEnumerable<IAppendage> Appendages{ get; }
virtual void growl(){ ... }
virtual int eat(Food food){
... test if likes
... many operations
chew()
...
stomach.fill(food);
}
}
interface IAppendage {
void Move();
}
class Wings : IAppendage {}
class Legs: IAppendage {}
class Flippers : IAppendage {}
class Movement {
private:
IAppendage AppendageForMovement { get; }
public :
void Go(){
AppendageForMovement.Move();
}
}
class FlyingMovement : Movement {}
class RunningMovement : Movement {}
class SwimmingMovement : Movement {}
class AmphibiousAnimal extends Animal {
private:
Flippers flipper;
Legs leg;
virtual IEnumerable<Movement > Movements { get { return new Movement [] { new SwimmingMovement( flipper ), new RunningMovement( leg ) } ; }
virtual IEnumerable<IAppendage> Appendages { get { return new IAppendage[] {new Wings() } }
public:
void fly(){ // find flying movement
...
flyingMovement.Go();
...
}
}
类动物{
私人:
出生地;
字符串名;
列出喜欢吃的食物;
胃;
公众:
虚拟IEnumerable移动{get;}
虚拟IEnumerable附件{get;}
虚拟空咆哮(){…}
虚拟int eat(食品){
…测试是否喜欢
…许多行动
咀嚼
...
填饱(食物);
}
}
接口IAppendage{
无效移动();
}
类翼:IAppendage{}
类腿:IAppendage{}
类翻转器:IAppendage{}
阶级运动{
私人:
IAppendage附录移动{get;}
公众:
void Go(){
AppendageForMovement.Move();
}
}
类FlyingMovement:Movement{}
类运行移动:移动{}
类SwimmingMovement:移动{}
两栖动物纲动物{
私人:
鳍状肢;
腿;
虚拟IEnumerable移动{get{返回新移动[]{new SwimmingMovement(flipper),new RunningMovement(leg)};}
虚拟IEnumerable附件{get{return new IAppendage[]{new Wings()}}
公众:
void fly(){//查找飞行运动
...
flyingMovement.Go();
...
}
}
这是一个粗略的例子,但希望它能给你一个想法。与其尝试将所有功能绑定到基类中,不如尝试将你需要的功能传入。如果你需要多种类型的功能(例如跑步、散步和游泳)然后,您只需传入更多的帮助器类即可提供该功能。这里面甚至没有问号。您有问题吗,或者这只是一个大脑转储?问题是:如何重写此代码以删除多重继承?我知道这是一个老问题,但今天解决此问题的最佳方法是使用mixin或traits。请参阅: