实现继承/重用来自多个父节点的功能/属性
本文关键字:父节点 功能 属性 继承 实现 | 更新日期: 2023-09-27 18:11:45
注意:在标记为重复或关闭之前,请考虑阅读完整的问题,您可能更愿意建议编辑而不是关闭它。
更新是的,我知道c#不允许多重继承,但当然它的一些时间需要实际如下场景,所以请指导,要么为什么不应该需要或如何实现
我需要继承/重用来自不同类的功能/成员在一个孩子。我有一个类
abstract class Hurdle
{
public virtual void setPositionInCells(){somecode_sp();}
public virtual void OnHit(){somecode_h();}
}
我真正需要的类别是MovableSingleCellHurdle
, MovableMultiCellHurdle
, StationarySingleCellHurdle
和StationaryMultiCellHurdle
但是在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;
}