What is good design in this simple case:
Let's say I have a base class Car with a method FillTank(Fuel fuel) where
fuel is also a base class which have several leaf classes, diesel, ethanol etc.
On my leaf car class DieselCar.FillTank(Fuel fuel) only a certain type of fuel
is allowed (no surprises there:)). Now here is my concern, according to my interface every car can be tanked with any fuel, but that seems wrong to me, in every FillTank() implementation check the input fuel for the correct type and if not throw error or something.
How can I redesign such case to a more accurate one, is it even possible?
How to design a base method which takes a base-class for input without getting these "strange results"?
Use a generic base class (if your language supports it (the below is C#)):
public abstract class Car<TFuel> where TFuel : Fuel
{
public abstract void FillTank(TFuel fuel);
}
Basically this enforces any class that inherits from car to specify which type of fuel it uses. Furthermore, the Car class imposes a restriction that TFuel must be some subtype of the abstract Fuel class.
Lets say we have some class Diesel which is simple:
public class Diesel : Fuel
{
...
}
And a car which only runs on diesel:
public DieselCar : Car<Diesel>
{
public override void FillTank(Diesel fuel)
{
//perform diesel fuel logic here.
}
}
Object-oriented programming alone cannot handle this problem well. What you need is generic programming (C++ solution shown here):
template <class FuelType>
class Car
{
public:
void FillTank(FuelType fuel);
};
Your diesel car is then just a specific car, Car<Diesel>.
If there is a hard boundary between types of cars and types of fuel, then FillTank() has no business being in the base Car class, since knowing that you have a car doesn't tell you what kind of fuel. So, for this to ensure correctness at compile time, FillTank() should be defined in the subclasses, and should only take the Fuel subclass that works.
But what if you have common code that you don't want to repeat between the subclasses? Then you write a protected FillingTank() method for the base class that the subclass's function calls. Same thing goes for Fuel.
But what if you have some magic car that runs on multiple fuels, say diesel or gas? Then that car becomes a subclass of both DieselCar and GasCar and you need to make sure that Car is declared as a virtual superclass so you don't have two Car instances in a DualFuelCar object. Filling the tank should Just Work with little or no modification: by default, you'll get both DualFuelCar.FillTank(GasFuel) and DualFuelCar.FillTank(DieselFuel), giving you an overloaded-by-type function.
But what if you don't want the subclass to have a FillTank() function? Then you need to switch to run time checking and do what you thought you had to: make the subclass check Fuel.type and either throw an exception or return an error code (prefer the latter) if there is a mismatch. In C++, RTTI and dynamic_cast<> are what I would recommend. In Python, isinstance().
a double dispatch can be used for this: accept some fuel before before filling. Mind you that in language that don't support it directly, you introduce dependencies
It sounds like you just want to restrict the type of fuel that goes into your diesel car. Something like:
public class Fuel
{
public Fuel()
{
}
}
public class Diesel: Fuel
{
}
public class Car<T> where T: Fuel
{
public Car()
{
}
public void FillTank(T fuel)
{
}
}
public class DieselCar: Car<Diesel>
{
}
Would do the trick e.g.
var car = new DieselCar();
car.FillTank(/* would expect Diesel fuel only */);
Essentially what you are doing here is allowing a Car to have specific fuel types. It also allows you to create a car that would support any type of Fuel (the chance would be a fine thing!). However, in your case, the DieselCar, you would just derive a class from car and restrict it to using Diesel fuel only.
use the is operator to check against the accepted classes, and you can throw an exception in the constructor
I think the accepted method would be to have a ValidFuel(Fuel f) method in your base class that throws some sort of NotImplementedException (different languages have different terms) if the "leaf" cars don't override it.
FillTank could be then be entirely in the base class and call ValidFuel to see if it's valid.
public class BaseCar {
public bool ValidFuel(Fuel f) {
throw new Exception("IMPLEMENT THIS FUNCTION!!!");
}
public void FillTank(Fuel fuel) {
if (!this.ValidFuel(fuel))
throw new Exception("Fuel type is not valid for this car.");
// do what you'd do to fill the car
}
}
public class DieselCar:BaseCar {
public bool ValidFuel(Fuel f) {
return f is DeiselFuel
}
}
In a CLOS-like system, you could do something like this:
(defclass vehicle () ())
(defclass fuel () ())
(defgeneric fill-tank (vehicle fuel))
(defmethod fill-tank ((v vehicle) (f fuel)) (format nil "Dude, you can't put that kind of fuel in this car"))
(defclass diesel-truck (vehicle) ())
(defclass normal-truck (vehicle) ())
(defclass diesel (fuel) ())
(defmethod fill-tank ((v diesel-truck) (f diesel)) (format nil "Glug glug"))
giving you this behaviour:
CL> (fill-tank (make-instance 'normal-truck) (make-instance 'diesel))
"Dude, you can't put that kind of fuel in this car"
CL> (fill-tank (make-instance 'diesel-truck) (make-instance 'diesel))
"Glug glug"
Which, really, is Common Lisp's version of double dispatch, as mentioned by stefaanv.
you can extend your original Car interface
interface Car {
drive();
}
interface DieselCar extends Car {
fillTank(Diesel fuel);
}
interface SolarCar extends Car {
chargeBattery(Sun fuel);
}
}
Related
I have an interface, say IVehicle, which is implemented in 100s of classes, some of them are variety of 4 wheeler and some are two wheeler dervied types.
I need to introduce a new method for all the 4 wheeler classes, lets say there are 50 of them. My challenge is to reduce the effort as much as I can.
I suggested, to introduce a new interface / abstract class with a method definition. But this require to change every 4 wheeler class declaration and extend with an extra parent.
Is there any possible way?
If you really want to avoid changing all those classes and want a solution that can be considered to be OO, one thing you can do is decorate those classes where they are used and need this extra behaviour.
I'll use C# for example code as you mentioned you're looking for C#/Java solution.
interface IVehicle
{
void DoThisNormalThing();
// ...
}
interface IBetterVehicle : IVehicle
{
void DoThisNeatThing();
}
class FourWheelVehicle : IVehicle
{
public void DoThisNormalThing()
{
// ...
}
// ...
}
class BetterFourWheelVehicle : IBetterVehicle
{
private readonly _vehicle;
public BetterFourWheelVehicle(IVehicle vehicle)
{
_vehicle = vehicle;
}
public void DoThisNormalThing()
{
_vehicle.DoThisNormalThing();
}
public void DoThisNeatThing()
{
// ...
}
// ...
}
Then usage:
var vehicle = new FourWheelVehicle();
var betterVehicle = new BetterFourWheelVehicle(vehicle);
betterVehicle.DoThisNeatThing();
This can be done using extension methods as well (and would result in a little less code and fewer allocated objects), but as this question is tagged with [oop] I wouldn't say extension methods are an OO construct. They're much more aligned with procedural style as they turn your objects into bags of procedures.
Why does object's type refer to its interface? Why the term type is used here? In terms of C++ I am not able to understand it.
Gamma, Erich. Design Patterns: Elements of Reusable Object-Oriented
Software (Addison-Wesley Professional Computing Series) (Kindle
Locations 593-596). Pearson Education. Kindle Edition.
An object’s class defines how the object is implemented. The class
defines the object’s internal state and the implementation of its
operations. In contrast, an object’s type only refers to its
interface—the set of requests to which it can respond. An object can
have many types, and objects of different classes can have the same
type.
An oversimplification...
Interface - a list of things that a class have and the things that it can do... a list of things that answer the "Whats"
Implementation - answers the question on "How" the "Whats" are accomplished.
Example:
An interface IPackageMover that does 2 things and 2 classes (types) that actually implements the interface (and also do other things aside from the interface requires)
// the interface
public interface IPackageMover
{
string GetName();
void public void MoveTo(Package package, string newAddress);
}
// the "type" that has the implementation
public class JoeThePackageMover : IPackageMover
{
public string GetName()
{
return "Joe";
}
public void MoveTo(Package package, string newAddress)
{
PickUp(package);
Drive(newAddress);
DropOff(package);
}
public void PickUp(Package package)
{
// do stuff
}
public void Drive(string newAddress)
{
// do stuff
}
public void DropOff(Package package)
{
// do stuff
}
}
// another "type" with the same interface
public class PassTheBuckPackageMover : IPackageMover
{
public string GetName()
{
return "What do you want it to be?";
}
public void MoveTo(Package package, string newAddress)
{
var joe = new JoeThePackageMover();
joe.MoveTo(package, newAddress);
}
public void Chill()
{
//do stuff
}
}
Why does object's type refer to its interface? Why the term type is used here? In terms of C++ I am not able to understand it.
Objects in OOP are not very different from the real world. For example :
A Car IS-A Vehicle. By this definition, a Car has the ability to transport people/cargo from one place to another.
A Car is also a Car. By this definition, it has the ability to be driven using a steering wheel.
In the above example, a Car IS-A Car and a Car is also a Vehicle because it can be driven using a steering wheel to move cargo/people from one place to another. In other words, the type of an object in the real world is defined by the things you can do with it (vis-à-vis it's interface.)
If we use the above analogy in programming, Car is a subclass of Vehicle and code that has a Car object can use all functions from Vehicle as well as Car. This would mean that a Car IS-A Vehicle and a Car. In conclusion, the type of object is defined by its interface, i.e the set of operations it supports.
I have two objects, Bird and Dog. Bird and Dog have identical implementations for about 50% of methods/properties but different unrelated methods and properties for the other 50%.
I'm refactoring and I don't know what is the best strategy.
I tried defining a superclass Animal to implement common methods in the superclass and let the children classes define their own methods/properties.
I wrote a factory that returned one or the other - this all seems right... but I'm confused when writing the calling code.. e.g.
public class Animal{
public string Talk(){ return "yak yak yak";
}
public class Dog:Animal{
public string Walk(){ return "walk walk walk"; }
}
public class Bird:Animal{
public string Fly(){ return "flap flap flap"; }
}
...
Animal thing = CreatureFactory.GetCreature(modifier);
When I want to use thing to Talk there's no problem,
Debug.Print(thing.Talk());
but what about when as the programmer I know I want it to Fly do I cast it to Bird? That seems wrong... but defining a Fly method on Dog seems wrong too.
You either cast it to a bird:
Debug.Print(((Bird)thing).Fly());
or you treat it as a bird the whole time:
// depending on how the factory works, might not need the cast
Bird thing = (Bird) CreatureFactory.GetCreature(modifier);
Debug.Print(bird.Fly());
Given your example, when you want your Animal to fly, the class doing the flying is working with the wrong class -- it should be using the Bird itself or some ICanFly interface.
While the other answers said you can do it with casting, the readability of your code will suffer because of it. When you have factories creating your objects, there's absolutely no reason you should be casting those objects to another type. There's also a solid argument that your classes are violating the Single Responsibility Principle when you start casting to other types.
The way I would approach it is to have the factory method return a concrete type rather than the superclass. You can still pass it to methods that can operate on the superclass, but you have an item of the concrete class to work with when needed and don't need to cast it.
Bird bird = CreatureFactory.GetBird();
or
Dog dog = CreatureFactory.GetDog();
Now, you can still use them as an Animal.
public class Trainer
{
public void TeachToSpeak( Animal animal )
{
...
animal.Talk();
}
}
But since they are typed to the concrete class, you can make use of the methods they don't share as appropriate.
I would say:
if your dog has also a methods that gives the idea of "movement", I would change the name of fly and walk to "move" and then call it.
If your dog doesn't have anything like that, the dev shouldn't be able to call it on an anymal object, because not all animals can fly :)
For one thing, I would put a virtual method on the base class called Move() and override it in the derived classes.
(The following is C#)
public abstract class Animal {
public string Talk() { return "yak yak yak"; }
public virtual string Move();
}
public class Dog : Animal {
public override string Move() { return "walk walk walk"; }
}
public class Bird : Animal {
public override string Move() { return "flap flap flap"; }
}
But to answer your question, if you want the animal to move if (and only if) it can fly, you could define an IFlyingAnimal interface and implement it with Bird. Then you can test whether an Animal implements that interface. If it does, cast it to IFlyingAnimal and call its Fly() method.
public interface IFlyingAnimal {
string Fly();
}
public class Bird : Animal, IFlyingAnimal {
public string Fly(){ return "flap flap flap"; }
}
//later, in your main program
public string FlyIfYouCan(Animal animal) {
if (animal is IFlyingAnimal)
return ((IFlyingAnimal)animal).Fly();
return "I can't fly!";
}
You don't have to use an interface; you could just use if (animal is Bird) instead. But it's much better practice to do it this way; birds aren't the only animals that can fly, so you're making the decision based on what your item does, not what it is. That's what interfaces are for.
I have looked around and could not find any similar question.
Here is the paragraph I got from Wikipedia:
Polymorphism is not the same as method overloading or method overriding. Polymorphism is only concerned with the application of specific implementations to an interface or a more generic base class. Method overloading refers to methods that have the same name but different signatures inside the same class. Method overriding is where a subclass replaces the implementation of one or more of its parent's methods. Neither method overloading nor method overriding are by themselves implementations of polymorphism.
Could anyone here explain it more clearly, especially the part "Polymorphism is not the same as method overriding"? I am confused now. Thanks in advance.
Polymorphism (very simply said) is a possibility to use a derived class where a base class is expected:
class Base {
}
class Derived extends Base {
}
Base v = new Derived(); // OK
Method overriding, on the other hand, is as Wiki says a way to change the method behavior in a derived class:
class Shape {
void draw() { /* Nothing here, could be abstract*/ }
}
class Square extends Shape {
#Override
void draw() { /* Draw the square here */ }
}
Overloading is unrelated to inheritance, it allows defining more functions with the same name that differ only in the arguments they take.
You can have polymorphism in a language that does not allow method overriding (or even inheritance). e.g. by having several different objects implement the same interface. Polymorphism just means that you can have different concrete implementations of the same abstract interface. Some languages discourage or disallow inheritance but allow this kind of polymorphism in the spirit of programming with abstractions.
You could also theoretically have method overriding without polymorphism in a language that doesn't allow virtual method dispatch. The effect would be that you could create a new class with overridden methods, but you wouldn't be able to use it in place of the parent class. I'm not aware of any mainstream language that does this.
Polymorphism is not about methods being overridden; it is about the objects determining the implementation of a particular process. An easy example - but by no means the only example - is with inheritance:
A Novel is a type of Book. It has most of the same methods, and everything you can do to a Book can also be done to a Novel. Therefore, any method that accepts a Book as an argument can also deal with a Novel as an argument. (Example would include .read(), .write(), .burn()). This is, per se, not referring to the fact that a Novel can overwrite a Book method. Instead, it is referring to a feature of abstraction. If a professor assigns a Book to be read, he/she doesn't care how you read it - just that you do. Similarly, a calling program doesn't care how an object of type Book is read, just that it is. If the object is a Novel, it will be read as a Novel. If it is not a novel but is still a book, it will be read as a Book.
Book:
private void read(){
#Read the book.
}
Novel:
private void read(){
#Read a book, and complain about how long it is, because it's a novel!
}
Overloading methods is just referring to having two methods with the same name but a different number of arguments. Example:
writeNovel(int numPages, String name)
writeNovel(String name)
Overloading is having, in the same class, many methods with the same name, but differents parameters.
Overriding is having, in an inherited class, the same method+parameters of a base class. Thus, depending on the class of the object, either the base method, or the inherited method will be called.
Polymorphism is the fact that, an instance of an inherited class can replace an instance of a base class, when given as a parameters.
E.g. :
class Shape {
public void draw() {
//code here
}
public void draw(int size) {
//this is overloading
}
}
class Square inherits Shape {
public void draw() {
//some other code : this is overriding
}
public void draw(color c) {
//this is overloading too
}
}
class Work {
public myMethod(Shape s) {
//using polymophism, you can give to this method
//a Shape, but also a Square, because Square inherits Shape.
}
}
See it ?
Polymorphing is the fact that, the same object, can be used as an instance of its own class, its base class, or even as an interface.
Polymorphism refers to the fact that an instance of a type can be treated just like any instance of any of its supertypes. Polymorphism means 'many forms'.
Say you had a type named Dog. You then have a type named Spaniel which inherits from Dog. An instance of Spaniel can be used wherever a Dog is used - it can be treated just like any other Dog instance. This is polymorphism.
Method overriding is what a subclass may do to methods in a base class. Dog may contain a Bark method. Spaniel can override that method to provide a more specific implementation. Overriding methods does not affect polymorphism - the fact that you've overriden a Dog method in Spaniel does not enable you to or prevent you from treating a Spaniel like a dog.
Method overloading is simply the act of giving different methods which take different parameters the same name.
I hope that helps.
Frankly:
Polymorphism is using many types which have specific things in common in one implementation which only needs the common things, where as method overloading is using one implementation for each type.
When you override a method, you change its implementation. Polymorphism will use your implementation, or a base implementation, depending on your language (does it support virtual methods?) and depending on the class instance you've created.
Overloading a method is something else, it means using the same method with a different amount of parameters.
The combination of this (overriding), plus the possibility to use base classes or interfaces and still call an overriden method somewhere up the chain, is called polymorphism.
Example:
interface IVehicle
{
void Drive();
}
class Car : IVehicle
{
public Drive() { /* drive a car */ }
}
class MotorBike : IVehicle
{
public Drive() { /* drive a motorbike */ }
}
class Program
{
public int Main()
{
var myCar = new Car();
var myMotorBike = new MotorBike();
this.DriveAVehicle(myCar); // drive myCar
this.DriveAVehicle(myMotorBike); // drive a motobike
this.DriveAVhehicle(); // drive a default car
}
// drive any vehicle that implements IVehicle
// this is polymorphism in action
public DriveAVehicle(IVehicle vehicle)
{
vehicle.Drive();
}
// overload, creates a default car and drives it
// another part of OO, not directly related to polymorphism
public DriveAVehicle()
{
// typically, overloads just perform shortcuts to the method
// with the real implemenation, making it easier for users of the class
this.DriveAVehicle(new Car());
}
}
I hear (and read on this site) a lot about "favour composition over inheritance".
But what is Compositon? I understand inheritance from the point of Person : Mammal : Animal, but I can't really see the definition of Compostion anywhere.. Can somebody fill me in?
Composition refers to combining simple types to make more complex ones. In your example, composition could be:
Animal:
Skin animalSkin
Organs animalOrgans
Mammal::Animal:
Hair/fur mammalFur
warm-blooded-based_cirulation_system heartAndStuff
Person::Mammal:
string firstName
string lastName
If you wanted to go totally composition (and get rid of all inheritance) it would look like this:
Animal:
Skin animalSkin
Organs animalOrgans
Mammal:
private Animal _animalRef
Hair/fur mammalFur
warm-blooded-based_cirulation_system heartAndStuff
Person:
private Mammal _mammalRef
string firstName
string lastName
The advantage to this approach is that the types Mammal and Person do not have to conform to the interface of their previous parent. This could be a good thing because sometimes a change to the superclass can have serious effects on the subclasses.
They still can have access to the properties and behaviours of these classes through their private instances of these classes, and if they want to expose these former-superclass behaviours, they can simply wrap them in a public method.
I found a good link with good examples here: http://www.artima.com/designtechniques/compoinh.html
Composition is simply the parts that make up the whole. A car has wheels, an engine, and seats. Inheritance is a "is a " relationship. Composition is a "has a" relationship.
There are three ways to give behavior to a class. You can write that behavior into the class; you can inherit from a class that has the desired behavior; or you can incorporate a class with the desired behavior into your class as a field, or member variable. The last two represent forms of code reuse, and the final one - composition - is generally preferred. It doesn't actually give your class the desired behavior - you still need to call the method on the field - but it puts fewer constraints on your class design and results in easier to test and easier to debug code. Inheritance has its place, but composition should be preferred.
class Engine
{
}
class Automobile
{
}
class Car extends Automobile // car "is a" automobile //inheritance here
{
Engine engine; // car "has a" engine //composition here
}
Composition - Functionality of an object is made up of an aggregate of different classes. In practice, this means holding a pointer to another class to which work is deferred.
Inheritance - Functionality of an object is made up of it's own functionality plus functionality from its parent classes.
As to why composition is preferred over inheritance, take a look at the Circle-ellipse problem.
An example of Composition is where you have an instance of a class within another class, instead of inheriting from it
This page has a good article explaining why people say "favour composition over inheritance" with some examples of why.
composition
simply mean using instance variables that are references to other objects.
For an illustration of how inheritance compares to composition in the code reuse department, consider this very simple example:
1- Code via inheritance
class Fruit {
// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {
System.out.println("Peeling is appealing.");
return 1;
}
}
class Apple extends Fruit {
}
class Example1 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
When you run the Example1 application, it will print out "Peeling is appealing.", because Apple inherits (reuses) Fruit's implementation of peel(). If at some point in the future, however, you wish to change the return value of peel() to type Peel, you will break the code for Example1. Your change to Fruit breaks Example1's code even though Example1 uses Apple directly and never explicitly mentions Fruit.
for more info ref
Here's what that would look like:
class Peel {
private int peelCount;
public Peel(int peelCount) {
this.peelCount = peelCount;
}
public int getPeelCount() {
return peelCount;
}
//...
}
class Fruit {
// Return a Peel object that
// results from the peeling activity.
public Peel peel() {
System.out.println("Peeling is appealing.");
return new Peel(1);
}
}
// Apple still compiles and works fine
class Apple extends Fruit {
}
// This old implementation of Example1
// is broken and won't compile.
class Example1 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
2- Code via composition
Composition provides an alternative way for Apple to reuse Fruit's implementation of peel(). Instead of extending Fruit, Apple can hold a reference to a Fruit instance and define its own peel() method that simply invokes peel() on the Fruit. Here's the code:
class Fruit {
// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {
System.out.println("Peeling is appealing.");
return 1;
}
}
class Apple {
private Fruit fruit = new Fruit();
public int peel() {
return fruit.peel();
}
}
class Example2 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
for more information ref