2012-05-03 79 views
-1

我正在研究多重继承,并且我读到它被认为是糟糕的设计。删除多重继承

我创建了一个示例,其中多重继承将是有用的,我还没有找到一种方法来重写它以删除多重继承。
此外,许多语言不支持多继承,需要新的设计。

'动物'类实现了许多动物所做的事情。
'AquaticAnimal'类实现了有关水的一切。
'TerrestrialAnimal'类实现了陆上动物的一切。

'两栖'类是为动物创造的,它可以做任何'水生动物'和'陆生动物'都可以做的事情。
该应用程序需要在类:动物园,水瓶座,平原和两栖类使用'两栖'动物。

尽管虚拟继承,钻石问题仍然存在,因为调用Amphibious.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); 
} 
+0

这里甚至没有问号。你有问题,还是只是一个脑转储? –

+0

现在的问题是:如何重写这段代码以删除多重继承? – Squall

回答

0

如果它的腿和脚蹼区别于水生和陆生动物,是不是真的有效说两栖的动物从两个继承?没有多少动物有腿和脚蹼。

无论哪种方式,你可以使用更多的,你传递需要到类件的组成方式:

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

这是一个有点粗糙的例子,但我希望它给你的想法。与其试图将所有功能绑定到基类尝试传递所需的功能。如果您需要多种类型的功能(例如跑步,步行和游泳),则只需传入更多的辅助类即可提供该功能。