I'm having problems understanding the difference between the use of Interfaces and abstract classes.
For example, please see the following UML diagramm:
What is the difference between these two?
I'll provide an explanation with code and a shorter explanation. If you don't want to read, just skip to the "plain English explanation" below.
Explanation with code
In C++ terms an abstract class is a class which implement some methods but don't implement other methods. That means: you can use some of their methods, but you'll have to implement the non-implemented ones.
Interfaces are pure classes in C++, that is, a class which doesn't implement anything and you must implement everything if you want your class to be conformant to that interface.
E.g. - try this out with the link below
#include <iostream>
using namespace std;
// Shape is abstract class: some methods are already available, some are not
class Shape
{
public:
// This is already implemented and ready for polymorphism
virtual void area() { cout<<"Shape area"<<endl;}
// You MUST implement this
virtual void implement_me() = 0;
};
class Circle : public Shape
{
public:
virtual void area() { cout<<"Circle area"<<endl;}
void implement_me() { cout<<"I implemented it just because I had to"<<endl;}
};
class HalfCircle : public Circle
{
public:
virtual void area() { cout<<"HalfCircle area"<<endl;}
};
// ShapeInterface is a pure class or interface: everything must be implemented!
class ShapeInterface
{
public:
virtual void area() = 0;
};
class CircleFromInterface : public ShapeInterface
{
public:
// You MUST implement this!
virtual void area() { cout<<"CircleFromInterface area from interface"<<endl;};
};
int main() {
Shape* ptr_to_base = new HalfCircle();
ptr_to_base->area(); // HalfCircle area, polymorphism
ptr_to_base->Shape::area(); // Shape area
ptr_to_base->implement_me(); // from Circle
ShapeInterface *ptr_to_base_int = new CircleFromInterface();
ptr_to_base_int->area(); // Just the derived has it
return 0;
}
http://ideone.com/VJKuZx
Plain-English Explanation
If you want the over-simplified version:
Interfaces are usually "contracts" which you need to adhere in toto: you need to agree with everything and implement everything or it doesn't work.
Abstract classes are partial-contracts, there are some things which you must agree/implement, but there's also some other stuff which is already there and you can choose whether to re-implement it (override) or just be lazy and use the existing ones.
Abstract classes used for dealing with code duplication between subclasses, because they can share common logic and data. Interfaces just define common contract of implementors.
So, if there is no common implementation to share, then use interface (I always start with interface). If some common implementation will appear, then extract abstract base class and move common code there. But even in this case I keep interface in hierarchy, because it's easy to mock and it is more abstract, which allows other classes not depend on any implementation at all.
In your case I think Circle and HalfCircle share some implementation. So I would go with moving common code to Circle and inheriting HalfCircle from itЖ
public class Circle : IShape
{
public double Radius { get; set; }
public virtual double Area
{
get { return Math.PI * Radius * Radius; }
}
}
public class HalfCircle : Circle
{
public override double Area
{
get { return base.Area / 2; }
}
}
If all shapes share some data or logic for calculating area, then it makes sense to declare base abstract Shape class for this common code. But if you will look at area calculation of square, there is nothing common with circle:
public class Square : IShape
{
public double Side { get; set; }
public double Area
{
get { return Side * Side; }
}
}
So IShape interface would be enough, because classes share only contract:
public interface IShape
{
double Area { get; }
}
An inheritance relationship, potentially using an abstract class, can usually be described as 'is a' and the implementation of an interface is a 'can be'. This concept can help when choosing which to use.
So if a Square 'is a' shape then inheritance would be an acceptable way of modelling this relationship.
Furthermore, an abstract class will give you the ability to provide common features. Where as an interface cannot contain any implementation.
Related
I have a problem to chose the between an abstract class without abstract methods OR a base class with an interface.
I have two implementation in my mind:
1.
Let's say I have a AbstractRenderer:
abstract class AbstractRenderer
{
protected $shape;
public function __construct(AbstractShape $shape)
{
$this->shape = $shape;
}
public function render(): string
{
return $this->shape->generate()->asArray();
}
}
and the WebRenderer would be like this:
class WebRenderer extends AbstractRenderer
{
}
2.
Have a base class and an interface like this:
Interface InterfaceRenderer
{
public function __construct(AbstractShape $shape);
public function render(): string;
}
and a base class that impediments the interface:
class BaseRenderer implements InterfaceRenderer
{
protected $shape;
public function __construct(AbstractShape $shape)
{
$this->shape = $shape;
}
public function render(): string
{
return $this->shape->generate()->toString();
}
}
again, my WebRenderer would be like this:
class WebRenderer extends BaseRenderer
{
}
I don't know which is the correct implementation, or there is a better way to implement this and what is the pros and cons of each.
Thanks
From the Renderer client’s perspective the 2 solutions are basically identical. As long as they depend on an abstract object (interface or an abstract class), you’ll have benefits of polymorphism. You’d lose those if you make them depend on WebRenderer (concrete object).
Interface’s benefits over abstract classes
doesn’t occupy inheritance
no fragile base class problem
Abstract classes provide
static methods (in many languages interface can’t have these)
protected implementation
Suppose I have a game, where there are buildings sorted by type. Each type is represented as a separate class, but sometimes I have to do some uncommon logic for the buildings of the same type. How could one implement this kind of behaviour?
For example, I can identify buildings by ID, so I can have a giant switch or command pattern inside the building type class. But I think that something is not right with this approach.
Another approach is to have different class for any divergent logic. But this proposes a lot of small classes.
This is what polymorphism aims to solve, and one of the big differences between procedural and oop programming. You can achieve it through extending a base class, or by implementing an interface. Here is extending a base class:
public abstract class Building {
abstract void destroy();
}
public BrickBuilding extends Building {
#Override
public void destroy() {
bricks.fallToGround();
}
}
public HayBuilding extends Building {
#Override
public void destroy() {
straw.blowInWind();
}
}
In places in your code where you would have used a switch statement to switch on building type, just hold a reference to the abstract Building type, and call method destroy() on it:
public class BuildingDestroyer {
public void rampage() {
for(Building building : allTheBuildings) {
// Could be a BrickBuilding, or a HayBuilding
building.destroy();
}
}
}
Or, to address your concern about having a lot of small types, you can 'inject' a destroy behaviour you want into a common building type, like so...albeing, you will end up with a lot of different destroy behaviour classes too...so, this might not be a solution.
public interface DestroyBehaviour {
void destroy(Building building);
}
public class Building {
private int id;
public DestroyBehaviour destroyBehaviour;
public Building(int id, DestroyBehaviour destroyBehaviour) {
this.id = id;
this.destroyBehaviour = destroyBehaviour;
}
public void destroy() {
destroyBehaviour.destroy(this); // or something along those lines;
}
}
You can get rid of the giant switch by having a BuildingFactory class which exposes a registerBuildingType(typeName, instanceCreatorFunc) method, that each building class calls (from a static initialize method for example) and that gets called with a unique string for that class (class name would suffice) and a static "create" method that returns a new instance.
This approach also has the advantage of being able to load new buildings from dynamically linked libraries.
Let's say I have the following method that, given a PaymentType, sends an appropriate payment request to each facility from which the payment needs to be withdrawn:
public void SendRequestToPaymentFacility(PaymentType payment) {
if(payment is CreditCard) {
SendRequestToCreditCardProcessingCenter();
} else if(payment is BankAccount) {
SendRequestToBank();
} else if(payment is PawnTicket) {
SendRequestToPawnShop();
}
}
Obviously this is a code smell, but when looking for an appropriate refactoring, the only examples I have seen involve cases where the code executed within the conditionals are clearly the responsibility of the class itself, e.g. with the standard example given:
public double GetArea(Shape shape) {
if(shape is Circle) {
Circle circle = shape As Circle;
return circle.PI * (circle.radius * circle.radius);
} else if(shape is Square) {
Square square = shape as Square;
return square.length * square.width;
}
}
GetArea() seems like a pretty reasonable responsibility for each Shape subclass, and can of course be refactored nicely:
public class Shape
{
/* ... */
public abstract double GetArea();
}
public class Circle
{
public override double GetArea()
{
return PI * (radius * radius);
}
}
However, SendRequestToPaymentFacility() does not seem like an appropriate responsibility for a PaymentType to have. (and would seem to violate the Single Responsibility Principle). And yet I need to send a request to an appropriate PaymentFacility based on the type of PaymentType - what is the best way to do this?
You could consider adding a property or method to your CandyBar class which indicates whether or not the CandyBar contains nuts. Now your GetProcessingPlant() method does not have to have knowledge of the different types of CandyBars.
public ProcessingPlant GetProcessingPlant(CandyBar candyBar) {
if(candyBar.ContainsNuts) {
return new NutProcessingPlant();
} else {
return new RegularProcessingPlant();
}
}
One option would be to add an IPaymentFacility interface parameter to the constructors for the individual PaymentType descendants. The base PaymentType could have an abstract PaymentFacility property; SendRequestToPaymentFacility on the base type would delegate:
public abstract class PaymentType
{
protected abstract IPaymentFacility PaymentFacility { get; }
public void SendRequestToPaymentFacility()
{
PaymentFacility.Process(this);
}
}
public interface IPaymentFacility
{
void Process(PaymentType paymentType);
}
public class BankAccount : PaymentType
{
public BankAccount(IPaymentFacility paymentFacility)
{
_paymentFacility = paymentFacility;
}
protected override IPaymentFacility PaymentFacility
{
get { return _paymentFacility; }
}
private readonly IPaymentFacility _paymentFacility;
}
Rather than wiring up the dependency injection manually, you could use a DI/IoC Container library. Configure it so that a BankAccount got a Bank, etc.
The downside is that the payment facilities would only have access to the public (or possibly internal) members of the base-class PaymentType.
Edit:
You can actually get at the descendant class members by using generics. Either make SendRequestToPaymentFacility abstract (getting rid of the abstract property), or get fancy:
public abstract class PaymentType<TPaymentType>
where TPaymentType : PaymentType<TPaymentType>
{
protected abstract IPaymentFacility<TPaymentType> PaymentFacility { get; }
public void SendRequestToPaymentFacility()
{
PaymentFacility.Process((TPaymentType) this);
}
}
public class BankAccount : PaymentType<BankAccount>
{
public BankAccount(IPaymentFacility<BankAccount> paymentFacility)
{
_paymentFacility = paymentFacility;
}
protected override IPaymentFacility<BankAccount> PaymentFacility
{
get { return _paymentFacility; }
}
private readonly IPaymentFacility<BankAccount> _paymentFacility;
}
public interface IPaymentFacility<TPaymentType>
where TPaymentType : PaymentType<TPaymentType>
{
void Process(TPaymentType paymentType);
}
public class Bank : IPaymentFacility<BankAccount>
{
public void Process(BankAccount paymentType)
{
}
}
The downside here is coupling the Bank to the BankAccount class.
Also, Eric Lippert discourages this, and he makes some excellent points.
One approach you can take here is to use the Command pattern. In this case, you would create and queue up the appropriate command (e.g. Credit Card, Bank Account, Pawn Ticket) rather than calling a particular method. Then you could have separate command processors for each command that would take the appropriate action.
If you don't want the conditional complexity here, you could raise a single type of command that included the payment type as a property, and then a command processor could be responsible for figuring out how to handle that request (with the appropriate payment processor).
Either of these could help your class follow Single Responsibility Principle by moving details of payment processing out of it.
I have a class, say Provider, that exposes its funcationality to the above service layers of the system. It has a public method, say GetX(). Now, there are two ways to get the X : XML way and non-XML way. Two "Library" classes implement these two ways, one for each.
Thus, the structure that happens is something as follows :
public class Provider
{
private XmlLib _xmlLib;
private NonXmlLib _nonXmlLib;
public X GetX( // parameters )
{
// validate the parameters
if ( // some condition)
X = _xmlLib.GetX();
else
X = _nonXmlLib.GetX();
return X;
}
// several other such methods
}
internal class XmlLib
{
public X GetX()
{
// Xml way to get X.
}
// several such things to get/send in XML way.
}
internal class NonXmlLib
{
public X GetX()
{
// NonXml way to get X.
}
// several such methods to get/send thing in non-XML way.
}
So its like, the Provider class becomes a sort of a dumb wrapper, which only validates the arguments, and based on one condition, decides which lib to call.
Is this a good implementation? Any better way to implement this?
Let the GetX method be in an interface. from that point on you can have as many classes that you want that implement the interface.
public interface ISomeInterface { X GetX(); }
Now build a class that will implement the factory design pattern (read about it if you do not know it) and let this class accept the condition which will enable it to decide which class that implements the above interface to return.
here's what I said through code:
public class XmlWay : ISomeInterface
{
public X GetX()
{
//your implementation
}
}
public class NonXmlWay : ISomeInterface
{
public X GetX()
{
// Another implementation
}
}
and finally the factory class
public class MyXFactory
{
public static ISomeInterface GetXImplementation(bool someCondition)
{
if (someCondition)
return new XmlWay();
else
return new NonXmlWay();
}
Now see how elegent your code will look:
ISomeInterface xGen = MyXFactory.GetXImplementation(true);
xGen.GetX();
Hope this helps.
From what I`ve learned, it is no good if you frequently use downcasting in class hierarchies.
I agree with that, but what are exceptions from this rule if any?
This is where my design of graphical editor shows thin: I have two hierarchies, where geometric figures hierarchy decoupled from graphic primitives one. Like this:
public class GeometricPrimitive {...}
public class RectangeGeometric: Geometric Primitive {...}
public class GraphicPrimitive {...}
public class Rectangle: GraphicPrimitive {
private RectangleGeometric figure;
...
}
So, every concrete graphic figure class encapsulates instance of concrete geometry class. Is that approach is the right one, or should I prefer more generical one? - unfortunately, downcasting would be used in this case:
public class GraphicPrimitive {
protected GeometryPrimitive figure;
....
}
public class Rectangle: GraohicPrimitive {
public Rectangle(Color c, TwoDPoint leftHighPoint, TwoDPoint rightLowPoint):
base(new RectangleGeometric(leftHighPoint.Point2D, rightLowPoint.Point2D), c) { }
#region Geometric Properties
public TwoDPoint LeftTopCorner {
get { return new TwoDPoint(base.color, (base.figure as RectangleGeometric).LeftTopCorner); }
}
public TwoDPoint RightBottomCorner {
get { return new TwoDPoint(base.color, (base.figure as RectangleGeometric).RightBottomCorner); }
}
While your question lacks some of the larger context about your application that would help with giving a specific answer, I'll try by giving you some ideas of how I would implement this using your code for inspiration.
I would start by inverting the relationship GeometryPrimitive and GraphicPrimitive. I see the the GeometryPrimitive hierarchy as the domain objects that make up your abstract scene graph and the GraphicPrimitive hierarchy as low level view components that translate a GeometryPrimitive into a set of pixels appropriate for drawing onto some kind of graphics context. The GeometryPrimitive subclasses hold all the state information necessary to describe themselves but no logic for translating that description into pixels. The GraphicPrimitive subclasses have all the pixel pushing logic, but no internal state. In effect, the GraphicPrimitive hierarchy represents a hierarchy of Command Objects.
In the GeometryPrimitive base class, include an abstract method called GetGraphicPrimitive(). In the GraphicPrimitive base class include an abstract method called Draw(Graphics g).
Within each GeometryPrimitive, include the appropriate GraphicPrimitive for drawing the object and an accessor method for accessing it. To draw the entire scene, walk your structure of GeometryPrimitive objects, asking each one for its GraphicPrimitive and then invoking the Draw() method.
abstract class GeometryPrimitive
{
public abstract GraphicsPrimitive GetGraphicsPrimitive();
}
abstract class GraphicsPrimitive
{
public abstract void Draw(Graphics g);
}
class RectangleGeometryPrimitive : GeometryPrimitive
{
public Point TopLeft {get; set;}
public Point BottomRight {get; set;}
private RectangleGraphicPrimitive gp;
public RectanglePrimitive(Point topLeft, Point bottomRight);
{
this.TopLeft = topLeft;
this.BottomRight = bottomRight;
this.gp = new RectangleGraphicsPrimitive(this);
}
public GraphicsPrimitive GetGraphicsPrimitive()
{
return gp;
}
}
class RectangleGraphicsPrimitive : GraphicsPrimitive
{
private RectangleGeometryPrimitive p;
public RectangleGraphicsPrimitive(RectangleGeometryPrimitive p)
{
this.p = p;
}
public void Draw(Graphics g)
{
g.DrawRectangle(p.TopLeft, p.BottomRight);
}
}
class CircleGeometryPrimitive : GeometryPrimitive
{
public Point Center {get; set;}
public int Radius {get; set;}
private CircleGraphicPrimitive gp;
public RectanglePrimitive(Point center, int radius);
{
this.Center = center;
this.Radius = radius;
this.gp = new CircleGraphicsPrimitive(this);
}
public GraphicsPrimitive GetGraphicsPrimitive()
{
return gp;
}
}
class CircleGraphicsPrimitive : GraphicsPrimitive
{
private CircleGeometryPrimitive p;
public CircleGraphicsPrimitive(CircleGeometryPrimitive p)
{
this.p = p;
}
public void Draw(Graphics g)
{
g.DrawCircle(p.Center, p.Radius);
}
}
As you can see above, no downcasting is required to draw GeometryPrimitives to the screen. With proper use of inheritance, you can also share GraphicsPrimitive objects between different GeometryPrimitives. For example, SquareGeometryPrimitive and RectangleGeometryPrimitive can both use RectangleGraphicsPrimitive if SquareGeometryPrimitive derives from RectangleGeometryPrimitive.
You don't give many details, so I can't really give my opinion about whether it is adequate to have the two hierarchies. We all know the costs of this parallelism, but only you can evaluate the advantages ...
I don't know your programming language. But a common solution to avoid the downcasting you mention, is to have a base class using parameterized types (called generics or templating). This works in Java, C++ and many modern languages.
The idea is that the precise type of the field base.figure is determined by each subclass. What you know in the base class is that it is a subtype T of GeometryPrimitive. In each subclass, you defined the precise type RectangleGeometric that replaces the T, so within this subclass the type is precise.
Java example:
public GraphicPrimitive<T extends GeometryPrimitive> {
protected T figure;
}
public Rectangle extends GraohicPrimitive<RectangleGeometric> {
// It appears in this class that the field was defined as
//protected RectangleGeometric figure;
public TwoDPoint getLeftTopCorner {
return new TwoDPoint(base.color, figure.LeftTopCorner);
}
}