我将尝试在一个简单的例子中提出我的问题......
假设我有一个抽象的基类Car.Car有一个基本的Engine对象.我在抽象Car类中有一个方法StartEngine(),它将引擎的起始委托给Engine对象.
如何允许Car的子类(如法拉利)将Engine对象声明为特定类型的引擎(例如,TurboEngine)?我需要另一个Car class(TurboCar)吗?
我正在继承一个普通的旧Engine对象,我不能在我的Car子类中重新声明(或覆盖)它作为TurboEngine.
编辑: 我知道我可以在我的法拉利课程中将任何Engine的子类插入myEngine参考中...但是我怎样才能调用只有TurboEngine暴露的方法?因为myEngine是作为基础引擎继承的,所以没有包含任何turbo内容.
谢谢!
抽象工厂模式正是针对这个问题.Google GoF抽象工厂{您的首选语言}
在下文中,请注意如何使用具体工厂生成"完整"对象(enzo,civic),或者您可以使用它们来生成相关对象的"族"(CarbonFrame + TurboEngine,WeakFrame + WeakEngine).最终,您总是会得到一个Car对象,它响应使用类型特定行为的accele().
using System; abstract class CarFactory { public static CarFactory FactoryFor(string manufacturer){ switch(manufacturer){ case "Ferrari" : return new FerrariFactory(); case "Honda" : return new HondaFactory(); default: throw new ArgumentException("Unknown car manufacturer. Please bailout industry."); } } public abstract Car createCar(); public abstract Engine createEngine(); public abstract Frame createFrame(); } class FerrariFactory : CarFactory { public override Car createCar() { return new Ferrari(createEngine(), createFrame()); } public override Engine createEngine() { return new TurboEngine(); } public override Frame createFrame() { return new CarbonFrame(); } } class HondaFactory : CarFactory { public override Car createCar() { return new Honda(createEngine(), createFrame()); } public override Engine createEngine() { return new WeakEngine(); } public override Frame createFrame() { return new WeakFrame(); } } abstract class Car { private Engine engine; private Frame frame; public Car(Engine engine, Frame frame) { this.engine = engine; this.frame = frame; } public void accelerate() { engine.setThrottle(1.0f); frame.respondToSpeed(); } } class Ferrari : Car { public Ferrari(Engine engine, Frame frame) : base(engine, frame) { Console.WriteLine("Setting sticker price to $250K"); } } class Honda : Car { public Honda(Engine engine, Frame frame) : base(engine, frame) { Console.WriteLine("Setting sticker price to $25K"); } } class KitCar : Car { public KitCar(String name, Engine engine, Frame frame) : base(engine, frame) { Console.WriteLine("Going out in the garage and building myself a " + name); } } abstract class Engine { public void setThrottle(float percent) { Console.WriteLine("Stomping on accelerator!"); typeSpecificAcceleration(); } protected abstract void typeSpecificAcceleration(); } class TurboEngine : Engine { protected override void typeSpecificAcceleration() { Console.WriteLine("Activating turbo"); Console.WriteLine("Making noise like Barry White gargling wasps"); } } class WeakEngine : Engine { protected override void typeSpecificAcceleration() { Console.WriteLine("Provoking hamster to run faster"); Console.WriteLine("Whining like a dentist's drill"); } } abstract class Frame { public abstract void respondToSpeed(); } class CarbonFrame : Frame { public override void respondToSpeed() { Console.WriteLine("Activating active suspension and extending spoilers"); } } class WeakFrame : Frame { public override void respondToSpeed() { Console.WriteLine("Loosening bolts and vibrating"); } } class TestClass { public static void Main() { CarFactory ferrariFactory = CarFactory.FactoryFor("Ferrari"); Car enzo = ferrariFactory.createCar(); enzo.accelerate(); Console.WriteLine("---"); CarFactory hondaFactory = CarFactory.FactoryFor("Honda"); Car civic = hondaFactory.createCar(); civic.accelerate(); Console.WriteLine("---"); Frame frame = hondaFactory.createFrame(); Engine engine = ferrariFactory.createEngine(); Car kitCar = new KitCar("Shaker", engine, frame); kitCar.accelerate(); Console.WriteLine("---"); Car kitCar2 = new KitCar("LooksGreatGoesSlow", hondaFactory.createEngine(), ferrariFactory.createFrame()); kitCar2.accelerate(); } }