实现继承/重用来自多个父节点的功能/属性

本文关键字:父节点 功能 属性 继承 实现 | 更新日期: 2023-09-27 18:11:45

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

更新是的,我知道c#不允许多重继承,但当然它的一些时间需要实际如下场景,所以请指导,要么为什么不应该需要或如何实现


我需要继承/重用来自不同类的功能/成员在一个孩子。我有一个类

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

我真正需要的类别是MovableSingleCellHurdle, MovableMultiCellHurdle, StationarySingleCellHurdleStationaryMultiCellHurdle

但是在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实践处理此场景

实现继承/重用来自多个父节点的功能/属性

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

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

显然,这只有在具有这种关系的类相对较少的情况下才实用。你拥有的这种关系越多,它就会呈指数级增长。

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

原因是基于LSP (Liskov替代原理)。

为了更清楚地了解LSP:您可能将破坏LSP,如下所述。但这些都只是学术研究。你可以忽略它,也可以根据你的里程来研究它。

解决方案很可能是委托。

首先,在更简单的类和更丰富的类之间需要一个have-a关系,就像这样:

class MovableSingleCellHurdle
{
    private MovableHurdle mh;
    private SingleCellHurdle sch;

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

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

如果一个方法有参数,传递它们,如果它们返回一些东西,返回它,像这样:

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

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

调用内部方法就是委托。

此外,您希望使用构造函数构造对象。这叫做构造函数注入:

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