实现多个父项的继承/重用功能/属性

时间:2016-10-06 13:13:47

标签: c# oop inheritance multiple-inheritance reusability

注意:在将其标记为重复或关闭之前,请考虑阅读完整问题,您可能更愿意建议编辑而非关闭。

更新是的我知道c#不允许多重继承,但是当然需要一段时间才能实现如下方案,所以请指导,为什么不需要它或者如何实现它

我需要继承/重用一个子节点中不同类的功能/成员。我有一个班级

abstract class Hurdle
{       
   public virtual void setPositionInCells(){somecode_sp();}
   public virtual void OnHit(){somecode_h();}
}

我需要的真正课程是MovableSingleCellHurdleMovableMultiCellHurdleStationarySingleCellHurdleStationaryMultiCellHurdle

但是在C#中我只能这样做

class SingleCellHurdle: Hurdle
{
 public int CellNumber;
 public override void setPositionInCells(){ base(); somecode_sp1();}
}
class MultipleCellHurdle: Hurdle 
{
 public int[] CellNumbers;
 public override void setPositionInCells(){ base(); somecode_sp2();}
}

class MovableHurdle: Hurdle
{
 public float HitForce;
 public override void OnHit() { base(); somecode_h1();}
}
class StationarHurdle: Hurdle
{
 public override void OnHit() { base(); somecode_h2();}
}

但我坚持做以下

class MovableSingleCellHurdle: MovableHurdle, SingleCellHurdle
{
   public override void OnHit() { base();}
   public override void setPositionInCells() { base();}
   public int getLastHitForce()
   {
       return HitForce;
   }
   public int getLastPositionCells()
   {
       return CellNumber;
   }
}

为什么我需要做的是,我不需要再次为真实班级复制setPosition()OnHit()的代码

我目前正在做的事情是没有继承/重用,因为它不允许我进行上述必需的结构

我应该在几年前学到这一点,但遗憾的是找不到专门针对这种继承方式的文章/博客。

如果您认为这个问题值得投票,那就没关系,但请指导我。如果我这样做完全错了,那么请指导我应该使用哪种方法?或者哪篇文章完全解释了使用最佳oop实践处理此场景

2 个答案:

答案 0 :(得分:0)

C#不支持多重继承。一种方法是这样的:

class Hurdle { ... }
class SingleCellHurdle : Hurdle { ... }
class MultipleCellHurdle : Hurdle { ... }
class MovableSingleCellHurdle : SingleCellHurdle { ... }
class MovableMultipleCellHurdle : MultipleCellHurdle { ... }    
class StationarySingleCellHurdle : SingleCellHurdle { ... }
class StationaryMultipleCellHurdle : MultipleCellHurdle { ... }

显然,只有相对较少的类具有这种关系时,这才是实用的。它会越多,这种关系就会呈指数增长。

答案 1 :(得分:0)

在这种情况下你不能也不能使用继承。

原因是基于LSP(Liskov Substitution Principle)。

要更清楚LSP:您可能break LSP as explained here。但这只是学术界的问题。您可以根据您的里程忽略或研究它。

解决方案很可能是授权。

首先,您需要在更简单的类和更丰富的类之间建立 has-a 关系,如下所示:

class MovableSingleCellHurdle
{
    private MovableHurdle mh;
    private SingleCellHurdle sch;

接下来,您委托对这些类的任何调用,如下所示:

    public void OnHit()
    {
        mh.OnHit();
        // or: sch.OnHit();
    }

如果mehtod有参数,请传递它们,如果它们返回某些内容,请将其返回,如下所示:

    public int SumAndFloor(double a, double b)
    {
        return internalDelegateClass.SumAndFloor(a, b);
    }

此模式称为合成,因为您通过利用更简单的对象来组合对象。

您调用内部方法的事实是delegation

此外,您希望使用构造函数构造对象。这称为constructor injection

    public MovableSingleCellHurdle(MovableHurdle mh, SingleCellHurdle sch)
    {
        this.mh = mh;
        this.sch = sch;
    }