How do I use composition with inheritance?

前端 未结 10 2387
星月不相逢
星月不相逢 2021-02-09 04:41

I\'m going to try to ask my question in the context of a simple example...

Let\'s say I have an abstract base class Car. Car has-a basic Engine object. I have a method

10条回答
  •  无人共我
    2021-02-09 05:33

    The Abstract Factory pattern is precisely for this problem. Google GoF Abstract Factory {your preferred language}

    In the following, note how you can either use the concrete factories to produce "complete" objects (enzo, civic) or you can use them to produce "families" of related objects (CarbonFrame + TurboEngine, WeakFrame + WeakEngine). Ultimately, you always end up with a Car object that responds to accelerate() with type-specific behavior.


         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();
            }
        }
    

提交回复
热议问题