Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 删除多重继承_Oop_Inheritance_Multiple Inheritance_Code Reuse - Fatal编程技术网

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。请参阅: