Is it ok to override a virtual method but provide no implementation? - oop

I'm trying to create a class heirachy for a game, there is an Item class which is the base class for all items in the game. The problem is that some derived items (like potion) might not implement some of the abstract methods defined by the item.
Is it ok for derived classes to implement an abstract method with "do nothing"?
Example: https://dotnetfiddle.net/jJABN1
using System;
using System.Collections.Generic;
public abstract class Item
{
public abstract void Use();
}
public class Potion : Item
{
public override void Use()
{
// do nothing
return;
}
}
public class Sword : Item
{
public override void Use()
{
Console.WriteLine("Sword used!");
return;
}
}
public class Program
{
public static void Main()
{
List<Item> items = new List<Item>();
Item potion = new Potion();
Item sword = new Sword();
items.Add(potion);
items.Add(sword);
for (int i = 0; i < items.Count; i++)
{
Item item = items[i];
item.Use();
}
}
}

One of Robert Martin's SOLID Principles - Interface Segregation Principle addresses this situation. It basically says that a client should not be exposed to methods it doesn't need.
An example of violating the Interface Segregation Principle:
// Abstraction
public abstract class Printer
{
public abstract void Print();
public abstract void Scan();
}
// Implementations
public class SomeAllInOnePrinter : Printer
{
public override void Print()
{
Console.WriteLine("Printing...");
}
public override void Scan()
{
Console.WriteLine("Scanning...");
}
}
public class SomeBasicPrinter : Printer
{
public override void Print()
{
Console.WriteLine("Printing...");
}
public override void Scan()
{
// Basic printers can't scan
}
}
This is usually solved by separating an abstract class to multiple smaller abstract classes that can optionally inherit one other:
// Abstractions
public abstract class Printer
{
public abstract void Print();
}
public abstract class AllInOnePrinter : Printer
{
public abstract void Scan();
}
// Implementations
public class SomeAllInOnePrinter : AllInOnePrinter
{
public override void Print()
{
Console.WriteLine("Printing...");
}
public override void Scan()
{
Console.WriteLine("Scanning...");
}
}
public class SomeBasicPrinter : Printer
{
public override void Print()
{
Console.WriteLine("Printing...");
}
}

Technically, there could be an edge-case (should be uncommon!) where a deriving class doesn't need to implement all the methods, in such a case I'd rather it to override and throw an error to signal the user that this method should not be used.
That said, in the provided example there is only one method, so the question is: if a derived class doesn't need this method - why do you need to inherit the abstract class to begin with? if it's just in order to provide an example that's understandable - but better improve the example to include other methods that are used in the derived class.

Related

use 2 class by only calling a single class

class merged(){
//i want to be able to use class sample1 and sample2 by just calling this merged class
}
class sample1(){}
class sample2(){}
Or doing this isnt ideal? can you please suggest how can I implement this more efficiently?
Composition?
Class merged(){
sample1 s1 = new sample1();
sample1 s2 = new sample2();
void doSomething1()
{
s1.dosomething();
}
void doSomething2()
{
s2.dosomething();
}
}
You can go one of the ways (or a mixture of a couple of ways) as shown below (Note: Java convention is to have the first letter of class names capital):
public interface Sample1() {
// abstract methods
}
public class Sample2() {
// whatever
}
public class Merged() extends Sample2 implements Sample1 {
// whatever
}
OR
public class Sample1() {
// abstract methods
}
public class Sample2() {
// whatever
}
public class Merged() {
Sample1 ob = new Sample1();
Sample2 ob2 = new Sample2();
}
OR
public interface Sample1() {
// abstract methods
}
public abstract Sample2() {
// abstract and other methods
}
public class Merged() extends Sample2 implements Sample1 {
// whatever
}
OR
public interface Sample1() {
// abstract methods
}
public interface Sample2() {
// abstract methods
}
public class Merged() implements Sample1, Sample1 {
// whatever
}
You should do this with interfaces. Modern Object-Oriented programming languages don't support multiple inheritance (believe me, it's a good thing that they don't) so you need to fix this by using interfaces.
Here's an example in Java:
public interface GasolineUser {
public double getGasolineGallonsLeft();
}
public interface MusicPlayer {
public void playMusic();
}
public class Car implements GasolineUser, MusicPlayer {
public double getGasolineGallonsLeft(){
// return gallons left
}
public void playMusic(){
// play music
}
}
Note that Car in this case is both a GasolineUser AND a MusicPlayer, so it can be passed to any method that requires one or any method that requires the other. Similar inheritance exists in C#. For more information on the usefulness of interfaces, do a google search on OOP Interfaces.

design pattern query

i have a question regarding design patterns.
suppose i want to design pig killing factory
so the ways will be
1) catch pig
2)clean pig
3) kill pig
now since these pigs are supplied to me by a truck driver
now if want to design an application how should i proceed
what i have done is
public class killer{
private Pig pig ;
public void catchPig(){ //do something };
public void cleanPig(){ };
public void killPig(){};
}
now iam thing since i know that the steps will be called in catchPig--->cleanPig---->KillPig manner so i should have an abstract class containing these methods and an execute method calling all these 3 methods.
but i can not have instance of abstract class so i am confused how to implement this.
remenber i have to execute this process for all the pigs that comes in truck.
so my question is what design should i select and which design pattern is best to solve such problems .
I would suggest a different approach than what was suggested here before.
I would do something like this:
public abstract class Killer {
protected Pig pig;
protected abstract void catchPig();
protected abstract void cleanPig();
protected abstract void killPig();
public void executeKillPig {
catchPig();
cleanPig();
killPig();
}
}
Each kill will extend Killer class and will have to implement the abstract methods. The executeKillPig() is the same for every sub-class and will always be performed in the order you wanted catch->clean->kill. The abstract methods are protected because they're the inner implementation of the public executeKillPig.
This extends Avi's answer and addresses the comments.
The points of the code:
abstract base class to emphasize IS A relationships
Template pattern to ensure the steps are in the right order
Strategy Pattern - an abstract class is as much a interface (little "i") as much as a Interface (capital "I") is.
Extend the base and not use an interface.
No coupling of concrete classes. Coupling is not an issue of abstract vs interface but rather good design.
public abstract Animal {
public abstract bool Escape(){}
public abstract string SaySomething(){}
}
public Wabbit : Animal {
public override bool Escape() {//wabbit hopping frantically }
public override string SaySomething() { return #"What's Up Doc?"; }
}
public abstract class Killer {
protected Animal food;
protected abstract void Catch(){}
protected abstract void Kill(){}
protected abstract void Clean(){}
protected abstract string Lure(){}
// this method defines the process: the methods and the order of
// those calls. Exactly how to do each individual step is left up to sub classes.
// Even if you define a "PigKiller" interface we need this method
// ** in the base class ** to make sure all Killer's do it right.
// This method is the template (pattern) for subclasses.
protected void FeedTheFamily(Animal somethingTasty) {
food = somethingTasty;
Catch();
Kill();
Clean();
}
}
public class WabbitHunter : Killer {
protected override Catch() { //wabbit catching technique }
protected override Kill() { //wabbit killing technique }
protected override Clean() { //wabbit cleaning technique }
protected override Lure() { return "Come here you wascuhwy wabbit!"; }
}
// client code ********************
public class AHuntingWeWillGo {
Killer hunter;
Animal prey;
public AHuntingWeWillGo (Killer aHunter, Animal aAnimal) {
hunter = aHunter;
prey = aAnimal;
}
public void Hunt() {
if ( !prey.Escape() ) hunter.FeedTheFamily(prey)
}
}
public static void main () {
// look, ma! no coupling. Because we pass in our objects vice
// new them up inside the using classes
Killer ElmerFudd = new WabbitHunter();
Animal BugsBunny = new Wabbit();
AHuntingWeWillGo safari = new AHuntingWeWillGo( ElmerFudd, BugsBunny );
safari.Hunt();
}
The problem you are facing refer to part of OOP called polymorphism
Instead of abstract class i will be using a interface, the difference between interface an abstract class is that interface have only method descriptors, a abstract class can have also method with implementation.
public interface InterfaceOfPigKiller {
void catchPig();
void cleanPig();
void killPig();
}
In the abstract class we implement two of three available methods, because we assume that those operation are common for every future type that will inherit form our class.
public abstract class AbstractPigKiller implements InterfaceOfPigKiller{
private Ping pig;
public void catchPig() {
//the logic of catching pigs.
}
public void cleanPig() {
// the logic of pig cleaning.
}
}
Now we will create two new classes:
AnimalKiller - The person responsible for pig death.
AnimalSaver - The person responsible for pig release.
public class AnimalKiller extends AbstractPigKiller {
public void killPig() {
// The killing operation
}
}
public class AnimalSaver extends AbstractPigKiller {
public void killPing() {
// The operation that will make pig free
}
}
As we have our structure lets see how it will work.
First the method that will execute the sequence:
public void doTheRequiredOperation(InterfaceOfPigKiller killer) {
killer.catchPig();
killer.cleanPig();
killer.killPig();
}
As we see in the parameter we do not use class AnimalKiller or AnimalSever. Instead of that we have the interface. Thank to this operation we can operate on any class that implement used interface.
Example 1:
public void test() {
AnimalKiller aKiller = new AnimalKiller();// We create new instance of class AnimalKiller and assign to variable aKiller with is type of `AnimalKilleraKiller `
AnimalSaver aSaver = new AnimalSaver(); //
doTheRequiredOperation(aKiller);
doTheRequiredOperation(aSaver);
}
Example 2:
public void test() {
InterfaceOfPigKiller aKiller = new AnimalKiller();// We create new instance of class AnimalKiller and assign to variable aKiller with is type of `InterfaceOfPigKiller `
InterfaceOfPigKiller aSaver = new AnimalSaver(); //
doTheRequiredOperation(aKiller);
doTheRequiredOperation(aSaver);
}
The code example 1 and 2 are equally in scope of method doTheRequiredOperation. The difference is that in we assign once type to type and in the second we assign type to interface.
Conclusion
We can not create new object of abstract class or interface but we can assign object to interface or class type.

Design pattern to save/load an object in various format

I have an object: X, that can be saved or loaded in various formats: TXT, PDF, HTML, etc..
What is the best way to manage this situation? Add a pair of method to X for each format, create a new Class for each format, or exists (as I trust) a better solution?
I'd choose the strategy pattern. For example:
interface XStartegy {
X load();
void save(X x);
}
class TxtStrategy implements XStartegy {
//...implementation...
}
class PdfStrategy implements XStartegy {
//...implementation...
}
class HtmlStrategy implements XStartegy {
//...implementation...
}
class XContext {
private XStartegy strategy;
public XContext(XStartegy strategy) {
this.strategy = strategy;
}
public X load() {
return strategy.load();
}
public void save(X x) {
strategy.save(x);
}
}
I agree with #DarthVader , though in Java you'd better write
public class XDocument implements IDocument { ...
You could also use an abstract class, if much behavior is common to the documents, and in the common methods of base class call an abstract save(), which is only implemented in the subclasses.
I would go with Factory pattern. It looks like you can use inheritance/polymorphism with generics. You can even do dependency injection if you go with the similar design as follows.
public interface IDocument
{
void Save();
}
public class Document : IDocument
{
}
public class PdfDocument: IDocument
{
public void Save(){//...}
}
public class TxtDocument: IDocument
{
public void Save(){//...}
}
public class HtmlDocument : IDocument
{
public void Save(){//...}
}
then in another class you can do this:
public void SaveDocument(T document) where T : IDocument
{
document.save();
}
It depends on your objects, but it is possible, that visitor pattern (http://en.wikipedia.org/wiki/Visitor_pattern) can be used here.
There are different visitors (PDFVisitor, HHTMLVisitor etc) that knows how to serialize parts of your objects that they visit.
I would instead suggest the Strategy pattern. You're always saving and restoring, the only difference is how you do it (your strategy). So you have save() and restore() methods that defer to various FormatStrategy objects you can plug and play with at run time.

How to design around lack of multiple inheritance?

Using interfaces won't work because I want a single implementation. Using this solution would end in a lot of redundant code because I plan on having quite a few sub classes (composition vs inheritance). I've decided that a problem-specific design solution is what I'm looking for, and I can't think of anything elegant.
Basically I want classes to have separate properties, and for those properties to be attached at design time to any sub class I choose. Say, I have class 'ninja'. I would like to be able to make arbitrary sub classes such as 'grayNinja' where a gray ninja will always have a sword and throwing stars. Then possibly 'redNinja' who will always have a sword and a cape. Obviously swords, stars, and capes will each have their own implementation - and this is where I can't use interfaces. The closest solution I could find was the decorator pattern, but I don't want that functionality at runtime. Is the best solution an offshoot of that? Where inside the Black Ninja class constructor, I pass it through the constructors of sword and throwingStar? (those being abstract classes)
haven't coded in a while and reading hasn't gotten me too far - forgive me if the answer is simple.
Edit: Answered my own question. I can't mark it as 'answer' until tomorrow. Please let me know if there's a problem with it that I didn't catch. All the reading this problem forced me to do has been awesome. Learned quite a bit.
You want classes to have separate properties. Have you considered coding exactly that?
For example, you want a RedNinja that is-a Ninja that has-a sword and cape. Okay, so define Ninja to have an inventory, make it accessible through Ninja, and pass in an inventory through RedNinja's constructor. You can do the same thing for behaviors.
I've done once a similar app. with a earlier "C++" compiler that supported only single inheritance and no interfaces, at all.
// base class for all ninjas
public class Ninja {
// default constructor
public Ninja() { ... }
// default destructor
public ~Ninja() { ... }
} // class
public class StarNinja: public Ninja {
// default constructor
public StarNinja() { ... }
// default destructor
public ~StarNinja() { ... }
public void throwStars() { ... }
} // class
public class KatannaNinja: public Ninja {
// default constructor
public KatannaNinja() { ... }
// default destructor
public ~KatannaNinja() { ... }
public void useKatanna() { ... }
} // class
public class InvisibleNinja: public Ninja {
// default constructor
public InvisibleNinja() { ... }
// default destructor
public ~InvisibleNinja() { ... }
public void becomeVisible() { ... }
public void becomeInvisible() { ... }
} // class
public class FlyNinja: public Ninja {
// default constructor
public FlyNinja() { ... }
// default destructor
public ~FlyNinja() { ... }
public void fly() { ... }
public void land() { ... }
} // class
public class InvincibleNinja: public Ninja {
// default constructor
public InvincibleNinja() { ... }
// default destructor
public ~InvincibleNinja() { ... }
public void turnToStone() { ... }
public void turnToHuman() { ... }
} // class
// --> this doesn't need to have the same superclass,
// --> but, it helps
public class SuperNinja: public Ninja {
StarNinja* LeftArm;
InvincibleNinja* RightArm;
FlyNinja* LeftLeg;
KatannaNinja* RightLeg;
InvisibleNinja* Body;
// default constructor
public SuperNinja() {
// -> there is no rule to call composed classes,
LeftArm = new StarNinja();
RightArm = new InvincibleNinja();
LeftLeg = new FlyNinja();
RightLeg = new KatannaNinja();
Body = new InvisibleNinja();
}
// default destructor
public ~SuperNinja() {
// -> there is no rule to call composed classes
delete LeftArm();
delete RightArm();
delete LeftLeg();
delete RightLeg();
delete Body();
}
// --> add all public methods from peers,
// --> to main class
public void throwStars() { LeftArm->throwStars(); }
public void useKatanna() { RightLeg->useKatanna(); }
public void becomeVisible() { Body->becomeVisible() }
public void becomeInvisible() { Body->becomeInvisible() }
public void fly() { LeftLeg->fly() }
public void land() { LeftLeg->land() }
public void turnToStone() { RightArm->turnToStone(); }
public void turnToHuman() { RightArm->turnToHuman(); }
} // class
Im afraid, that the most close example is the composition design pattern. In order, to become more similar to inheritance, I make a generic base class that all composite classes share, and I make a main class that will be the result of the multiple inheritance, that has a copy of all the public methods of the component classes.
If you want to use interfaces, to enforce that main class have all important methods,
then make an interface that matches each composing class, and implemented in the main class.
public interface INinja {
public void NinjaScream() { ... }
} // class
public interface IStarNinja {
void throwStars();
} // class
public interface IKatannaNinja {
void useKatanna();
} // class
public interface IInvisibleNinja {
void becomeVisible();
void becomeInvisible();
} // class
public interface CFlyNinja {
void fly();
void land();
} // class
public interface IInvincibleNinja {
void turnToStone() { ... }
void turnToHuman() { ... }
} // class
// base class for all ninjas
public class CNinja: public INinja {
// default constructor
public CNinja() { ... }
// default destructor
public ~CNinja() { ... }
public void NinjaScream() { ... }
} // class
public class CStarNinja: public CNinja, INinja {
// default constructor
public CStarNinja() { ... }
// default destructor
public ~CStarNinja() { ... }
public void NinjaScream() { ... }
public void throwStars() { ... }
} // class
public class CKatannaNinja: public CNinja, IKatannaNinja {
// default constructor
public CKatannaNinja() { ... }
// default destructor
public ~CKatannaNinja() { ... }
public void NinjaScream() { ... }
public void useKatanna() { ... }
} // class
public class CInvisibleNinja: public CNinja, IInvisibleNinja {
// default constructor
public CInvisibleNinja() { ... }
// default destructor
public ~CInvisibleNinja() { ... }
public void becomeVisible() { ... }
public void becomeInvisible() { ... }
} // class
public class CFlyNinja: public CNinja, IFlyNinja {
// default constructor
public CFlyNinja() { ... }
// default destructor
public ~CFlyNinja() { ... }
public void fly() { ... }
public void land() { ... }
} // class
public class CInvincibleNinja: public CNinja, IInvincibleNinja {
// default constructor
public CInvincibleNinja() { ... }
// default destructor
public ~CInvincibleNinja() { ... }
public void turnToStone() { ... }
public void turnToHuman() { ... }
} // class
// --> this doesn't need to have the same superclass,
// --> but, it helps
public class CSuperNinja: public CNinja,
IKatannaNinja,
IInvisibleNinja,
IFlyNinja,
IInvincibleNinja
{
CStarNinja* LeftArm;
CInvincibleNinja* RightArm;
CFlyNinja* LeftLeg;
CKatannaNinja* RightLeg;
CInvisibleNinja* Body;
// default constructor
public CSuperNinja() {
// -> there is no rule to call composed classes
LeftArm = new CStarNinja();
RightArm = new CInvincibleNinja();
LeftLeg = new CFlyNinja();
RightLeg = new CKatannaNinja();
Body = new CInvisibleNinja();
}
// default destructor
public ~SuperNinja() {
// -> there is no rule to call composed classes
delete LeftArm();
delete RightArm();
delete LeftLeg();
delete RightLeg();
delete Body();
}
// --> add all public methods from peers,
// --> to main class
public void throwStars() { LeftArm->throwStars(); }
public void useKatanna() { RightLeg->useKatanna(); }
public void becomeVisible() { Body->becomeVisible() }
public void becomeInvisible() { Body->becomeInvisible() }
public void fly() { LeftLeg->fly() }
public void land() { LeftLeg->land() }
public void turnToStone() { RightArm->turnToStone(); }
public void turnToHuman() { RightArm->turnToHuman(); }
} // class
I know this solution is complex, but, seems that there is not another way.
Cheers.
Alright so mix-ins through extension methods are going to be my preferred route. I couldn't figure out how to use dynamic proxies in vb.net (seemed to require libraries with lots of documentation that didn't cover specifically what I needed). Dynamic proxies also seems to be a bit dirtier of a solution than using extension methods. Composition would have been what I defaulted to if the previous two didn't work.
So one problem with extension methods, is that the code gets a little dirtier if you want to hold variables. Not much though. Another problem is that all the extension methods must be defined in modules, so the code might look a little goofy to a new eye. I will solve this by defining my interface and module with the corresponding extension method in the same file.
finally, here's some sample vb.net code if you don't want to see a full fledged example through the link.
Imports System.Runtime.CompilerServices 'for extension methods
Public Interface ISword
End Interface
Public Interface IThrowingStar
End Interface
Module ExtensionMethods
<Extension()>
Public Sub swingSword(ByVal hasASword As ISword)
Console.WriteLine("Sword has been swung")
End Sub
<Extension()>
Public Sub throwStar(ByVal hasAStar As IThrowingStar)
Console.WriteLine("Star has been thrown")
End Sub
End Module
Public Class RedNinja
Inherits Ninja
Implements IThrowingStar, ISword
Public Sub New()
End Sub
End Class
Public MustInherit Class Ninja
private curHealth as Integer
Public Sub New()
curHealth = 100
End Sub
Public Function getHP() As Integer
Return curHealth
End Function
End Class
Module Module1
Sub main()
Console.WriteLine("Type any character to continue.")
Console.ReadKey()
Dim a As New RedNinja
a.swingSword() 'prints "Sword has been swung"
a.throwStar() 'prints "Star has been thrown"
Console.WriteLine("End of program - Type any key to exit")
Console.ReadKey()
End Sub
End Module
Dirty solution, if you simply must have multiple inheritance, is using something like dynamic proxies in Java.
But I guess you're probably programming in C#, and this is language agnostic question, so here goes language agnostic answer: check out composite and factory design patterns, that should give you some ideas.
Also, it might not be needed to pass everything in constructor. Check out IoC pattern as well.

How do I use composition with inheritance?

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 StartEngine() in the abstract Car class that delegates the starting of the engine to the Engine object.
How do I allow subclasses of Car (like Ferrari) to declare the Engine object as a specific type of engine (e.g., TurboEngine)? Do I need another Car class (TurboCar)?
I'm inheriting a plain old Engine object and I cannot re-declare (or override) it as a TurboEngine in my Car subclasses.
EDIT: I understand that I can plug any subclass of Engine into myEngine reference within my Ferrari class...but how can I call methods that only the TurboEngine exposes? Because myEngine is inherited as a base Engine, none of the turbo stuff is included.
Thanks!
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();
}
}
There's no need to specify a subclass of Car to have a TurboEngine as long as TurboEngine is a subclass of Engine. You can just specify an instance of TurboEngine as the Engine for your Ferrari. You could even put a DieselEngine in your Ferrari. They're all just Engines.
A Car has an Engine. A TurboEngine is an Engine. A Car can have a TurboEngine or a DieselEngine or a FlintstonesEngine. They're all Engines.
If you want to limit the type of Engine in your Car subclass (no LawnMowerEngine in a SportsCar), you can leave it declared as Engine and limit it in the setter methods.
The Car has an Engine relationship doesn't limit the applicable subclasses of Engine.
You can always use an abstract that is protected. The public "Start" will call the protected (that will be ovveride in the abstract class). This way the caller only see the Start() and not the StartEngine().
abstract class Car {
private Engine engine;
public Car() {
this.engine = new Engine();
}
protected Car(Engine engine) {
this.engine = engine;
}
public void Start()
{
this.StartEngine();
}
protected abstract void StartEngine();
}
public class Ferrari : Car
{
public Ferrari() {
}
protected override void StartEngine()
{
Console.WriteLine("TURBO ENABLE!!!");
}
}
-The way to use it:
Car c = new Ferrari();
c.Start();
I think this would work.
public class Car
{
private Engine engine;
public virtual Engine CarEngine
{
get { return engine;}
}
public StartEngine()
{
CarEngine.Start();
}
}
public class Engine
{
public virtual void Start()
{
Console.Writeline("Vroom");
}
}
public class TurboEngine : Engine
{
public override void Start()
{
Console.Writeline("Vroom pSHHHHHHH");
}
// TurboEngine Only method
public double BoostPressure()
{
}
}
public class Ferrari : Car
{
private TurboEngine engine;
public override Engine CarEngine
{
return engine;
}
}
Ferrari = car new Ferrari();
// Will call Start on TurboEngine()
car.StartEngine();
// Upcast to get TurboEngine stuff
Console.WriteLine(car.CarEngine as TurboEngine).BoostPressure();
You can use C# generics to get what you're looking for, here.
The distinction of using generics is that your Ferrari "knows" that its Engine is-a TurboEngine, while the Car class doesn't have to know anything new—only that EngineType is-an Engine.
class Program
{
static void Main(string[] args)
{
Ferrari ferarri = new Ferrari();
ferarri.Start();
ferarri.Boost();
}
}
public class Car<EngineType> where EngineType : Engine, new()
{
protected EngineType engine;
public Car()
{
this.CreateEngine();
}
protected void CreateEngine()
{
this.engine = new EngineType();
}
public void Start()
{
engine.Start();
}
}
public class Ferrari : Car<TurboEngine>
{
public void Boost()
{
engine.Boost();
}
}
public class Engine
{
public virtual void Start()
{
Console.WriteLine("Vroom!");
}
}
public class TurboEngine : Engine
{
public void Boost()
{
Console.WriteLine("Hang on to your teeth...");
}
public override void Start()
{
Console.WriteLine("VROOOOM! VROOOOM!");
}
}
As I understand your (updated) question, you're going to have to cast the car's engine to the TurboEngine type if you want to call TurboEngine methods on it. That results in a lot of checking to see if the car you have has a TurboEngine before you call those methods, but that's what you get. Not knowing what this car is actually standing in for, I can't think of any reason you couldn't have the engine and the turbo engine share the same interface - are there really new methods that the turbo supports, or does it just do the same things differently - but I guess this metaphor was going to fall apart sooner or later.
Do you have generics in your language? In Java I could do this:
class Engine {}
abstract class Car<E extends Engine>
{
private E engine;
public E getEngine() { return engine; }
}
class TurboEngine extends Engine {}
class Ferrari extends Car<TurboEngine>
{
// Ferrari now has a method with this signature:
// public TurboEngine getEngine() {}
}
I'm sure there's something similar in C#. You can then treat an instance of Ferrari as either an instance of the Ferrari subclass (with getEngine returning the TurboEngine) or as an instance of the Car superclass (when getEngine will return an Engine).
Depending on your particular language semantics, there are a few ways to do this. Off the cuff my initial thought would be to provide a protected constructor:
public class Car {
private Engine engine;
public Car() {
this(new Engine());
}
protected Car(Engine engine) {
this.engine = engine;
}
public void start() {
this.engine.start();
}
}
public class Ferrari {
public Ferrari() {
super(new TurboEngine());
}
}
don't expose the internals of your class in the interface - in other words, the public method of Car should be Start, not StartEngine
if you want to impose an internal structure (i.e. like having only 1 engine) then you need another abstract/base class Engine that can be specialized.
then you can construct a sports car out of parts by setting the m_engine member to a sporty subclass of Engine, et al
EDIT: note that in the real world, a turbocharger is not part of the engine, it is an add-on to the engine, with its own control interface... But if you want to include things like this in your ferrari engine, that's ok, just upcast in the SportsCar subclass to make your base Engine into a TurboEngine
but it would be better modeling to keep the components separate - that way you can upgrade your turbocharger (dual intake vs single intake, for example) without replacing the entire engine!
There are lots of ways it could be done.
I would favour having a setEngine() method on Car, then having the Ferrari constructor call setEngine() and pass in an instance of a TurboEngine.