c# – 如何在双层次结构中正确表示继承?
假设我们有两个继承层次结构,其核心:
Car -> SportsCar -> SuperCar 和 Engine -> TurboEngine -> FormulaOneEngine 汽车有发动机. SportsCar有TurboEngine和SuperCar有FormulaOneEngine.问题是如何在C#中正确表示这一点.假设我们这样做: class Car { Engine Engine; int HeadLamps; } class SportsCar: Car { TurboEngine TurboEngine; int Ailerons; } class SuperCar: SportsCar { FormulaOneEngine FormulaOneEngine; int FlyingSaucers; } 这解决了问题,但它看起来很丑陋!例如,SuperCar现在有三个成员,它们通常指向同一个实例(如果他们不这样做则更糟!)并且看起来也没必要.对于4级,5级或更多级别的深层次结构,这看起来非常难看: SuperCar.Engine SuperCar.SportsEngine SuperCar.FormulaOneEngine 理想情况下,所有类型的汽车应该只有一个名为Engine的成员,但它应该是不同的类型,具体取决于汽车: Car.Engine SportsCar.Engine //of type TurboEngine SuperCar.Engine //of type FormulaOneEngine 此外,这应该支持多态,所以我可以 List<Car> x = ... x.Add(myCar); x.Add(mySportsCar); x.Add(mySuperCar); foreach(Car c in x) { x.Engine ... } 所以使用“新”成员就出局了.我还希望能够直接调用每种引擎类型的特定方法: class Engine { int Capacity; } class TurboEngine: Engine { int TurboCharger; } class FormulaOneEngine: TurboEngine { int JetFuel; } myCar.Engine.Capacity = .... mySportsCar.Engine.TurboCharger = ... mySuperCar.Engine.JetFuel = ... 此外,我将能够使用正常的继承好东西: myCar.HeadLamps = ... mySportsCar.HeadLamps = .... mySportsCar.Ailerons = .... mySuperCar.HeadLamps = ... mySuperCar.Ailerons = .... mySuperCar.FlyingSaucers = .... 任何想法如何重构这个以达到目的,也看起来漂亮?实际代码可能使用4,5或更多级别的继承链.我错过了一些明显的或者可能是一些技巧吗? 解决方法
这是一个典型的通用案例:
编辑再一次 – 仍然是相同的概念,但继承链完全存在.您必须拥有隐藏属性(新)才能满足您的需要,但是由于您正在实现ICar界面,因此在获得混合集合时仍然可以获得基本属性.我认为这是你能做的最好的事情. public interface ICar { IEngine Engine { get; set; } } public abstract class BaseCar<T> : ICar where T : IEngine { public T Engine { get; set; } IEngine ICar.Engine { get { return Engine; } set { Engine = (T)value; } } } public class Car : BaseCar<Engine>,ICar { } public class SportsCar : Car,ICar { IEngine ICar.Engine { get { return Engine; } set { Engine = (TurboEngine)value; } } public new TurboEngine Engine { get { return (TurboEngine)base.Engine; } set { base.Engine = value; } } } public interface ISportsCar<T> : ICar where T : TurboEngine { } public class SuperCar : SportsCar,ISportsCar<FormulaOneEngine> { public new FormulaOneEngine Engine { get { return (FormulaOneEngine)base.Engine; } set { base.Engine = value; } } } public interface IEngine { } public class Engine : IEngine { } public class TurboEngine : Engine { } public class FormulaOneEngine : TurboEngine { } 你现在可以这样做: var cars = new List<ICar>(); cars.Add(new Car()); cars.Add(new SuperCar()); cars.Add(new SportsCar()); 请记住,Engine属性在此上下文中将是IEngine接口类型,这意味着您将无法访问每个类的唯一属性,并且如果您尝试分配错误的对象,则可能会遇到运行时异常到那个属性.但是,如果你说: var mySportsCar = new SportsCar(); mySportsCar.Engine // this will be strongly typed as TurboEngine (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |