views:

563

answers:

9

Possible Duplicate:
When to use an interface instead of an abstract class and vice versa?

Hi, I am teaching OOP concepts to non-programmers. I wanted to know how can you explain the difference between an interface and an abstract class.
What I am actually looking for, is a real world example that can help highlight the difference between the two.

+19  A: 

Here's a good comparison of the two: interface vs abstract class. I've copied a specific example from there below:

Interface

Interfaces are often used to describe the peripheral abilities of a class, not its central identity, e.g. An Automobile class might implement the Recyclable interface, which could apply to many otherwise totally unrelated objects.

Abstract class

An abstract class defines the core identity of its descendants. If you defined a Dog abstract class then Dalmatian descendants are Dogs, they are not merely dogable. Implemented interfaces enumerate the general things a class can do, not the things a class is.

casablanca
Both of those examples are excellent, +1
Tegeril
+1: I wouldn't be able to say it better than this.
Brian Driscoll
While I agree with most of this answer, using dogs to illustrate an abstract class is misleading (no offense). If there's only one thing students should understand, it's that OOD is about behavior, not classification. A dalmation doesn't *behave* any differently than a dog in every respect. It barks, wags its tail, and so on. There would be no need to create a derivative class for it.
@Jeff Mattfield: I didn't make up the example, but I would argue in favour of it. Classification *implies* differing behaviour and characteristics, otherwise you wouldn't classify it in the first place. For example, a dalmatian has a characteristic pattern of spots that not all species have.
casablanca
@casablanca: Classification in OOD is always about behavior. The visible characteristics of a dog would be represented in a Dog class as a property called "Appearance." This property would behave in a way that provides appearance data in a certain format. That is the behavior client classes of Dog would expect. To provide appearance data in another format is a change of behavior.
To extend the use of dogs: a dalmatian might or might not implement ITrainedDog, with its Sit(), Heel(), LieDown() methods. A concrete Dalmatian could also not be an ITrainedDog.
Jay
@Jeff Mattfield: In that case, you would end up extending the `Appearance` class to accommodate special features. No different from the original example and also doesn't reveal the fact that the dog is actually a dalmatian.
casablanca
@casablanca: There's no need for another class to know whether a dog is a dalmatian. Assume, for example, that the Dog class has an Appearance property that returned a bitmap. A Dalmation derivative class would be unnecessary because all the application needs to do is store a bitmap of a dalmatian in a Dog object.Taking your idea of extending an Appearance class, the situation doesn't change. The Dog class's Appearance property would return an Appearance object. A Dog object would have in its state any of the derivatives of Appearance. There's still no need for a Dalmatian class.
@Jeff Mattfield: Keep in mind that appearance isn't the only characteristic of a dog. Each species will eat differently, behave differently and have different physical abilities, yet these traits are unique to each species. Now why would you create a new Appearance class, a new Behaviour class and a new Abilities class for each species of dog (which you will probably never reuse except for this species) when you can simply put all of this into a single Dalmatian class?
casablanca
@casablanca: My point was that it is a misleading example of inheritance in software. Appearance is arguably the most distinguishing difference among dog breeds, leading students to think of appearance as being the factor in deciding how to structure a relevant class hierarchy in software. (In fact, you did so yourself in an earlier comment.) For illustrative purposes to students, I would prefer an example that illustrates that inheritance is an "acts-like-a" relationship rather than an "is-a" relationship.
@Jeff Mattfield: It is obvious you have a very limited view of dog behaviour. Were you to have any sense of behaviour modification in dogs you would see the need for descendant classes of dogs by breed group and sometimes even specific breeds. The fact that the behaviour differences happen to fall along classification lines does not invalidate the need for the distinction.
Marjan Venema
@Marjan Venema: Please. I'm no idiot. Quite frankly, I'd rather *not* understand the intricacies of dog classification. I'd rather leave that to domain experts and design an application that allows *them* to maintain their own classification system. I see a nightmare in having to maintain a class for each of the several hundred breeds of dog.
@Marjan Venema: My concern is that the typical student will infer from the dog example that developers should model software class hierarchies after real-world classification systems. That's not only incorrect but also often infeasible, especially with the example under discussion.
@Jeff MAttfield: My comment was in response to your first comment about the dog example. If you are worried about students inferring wrong things from an example, point that out. But don't do it by making over-generalized statements about a domain you have no knowledgde of and self-admittedly no desire of learning about.
Marjan Venema
@Marjan Venema: LOL. If asked to join a dog-related development project, I'll be sure to let the management know that you're far more qualified than I.
@Jeff Mattfield: LOL, deal!
Marjan Venema
+24  A: 

The player Interface

In my Java courses I often use this interface kind of image and ask: "What is this ?"

Every time someone will say "that's a player". From this image you can teach anybody what an interface is. This Interface allow any user to "play" something. Everybody knows what these buttons mean, even if you don't know what exactly will be done, you can use anything with this interface and you know that the little arrow will "play" and other arrows will probably send you forward or backward. Everything that will have those buttons will provide a standard behavior that any user will know before even starting to use them.

I usually try to avoid the "contract" word which can be misunderstood.

The DVD player Abstract class

And then from the Play Interface, I go to the VCR (or DVD) player. Every constructor of DVD player must add some special functions to transform a simple unknown player into a DVD player. For example the eject button. And they must correctly implement Player.
The play button will launch the content of the DVD.

But even if DVD Player provide the basic behavior of a DVD player, not everything is done. You can't simply have "a" DVD player, it has a brand and most of the time it has its own firmware. A this time you'll need to extend the DVD Player abstract class to add your own little components.

Colin Hebert
`+1` from me for this wonderful analogy. If the rest of your class is as good as this example, I wish you could teach more students...
sbi
Both examples are really just interfaces though - it's very hard to give a real-world example of abstract classes.
Michael
+1,000,000 for not using the word contract !!
user279521
@Michael in fact I emphasize the fact that a DVD player already define some behavior. Even if it isn't complete every DVD player will basically act the same way. And as you can't have "a" DVD player, it can't be instantiated and it's abstract.
Colin Hebert
You can't have "a" player either. I have to agree with Michael that the distinction isn't very clear in this example.
Lèse majesté
Colin, are you implying that the DVD / VCR player is an abstract class (or similar to) ?
@Lèse majesté, but you can't instantiate an interface. And a player doesn't have any property or fixed behavior, you just know what you can do with (call certain methods from the outside, such as public methods). @user84850 yes.
Colin Hebert
Colin, thanks. Your response has really helped alot.
@Michael: This might be a communication problem/misunderstanding. In C++, abstract base classes are used as interfaces. From this POV, interfaces are just a subset of abstract base classes: those which have only pure virtual functions without an implementation, no data members, and a default constructor. Still, the use of an abstract base class in C++ as an interface differs from other uses, although the languages does nothing to enforce the distinction.
sbi
A: 

For everything computer related, I use a cooking dinner example. I start by saying that hard drives are cabinets/storage closets. Memory is like your counter. Processor is the cooking apparatus (stove). You are like the system bus (moving things around, etc...). So when you boot a computer, you take your basic ingredients out of storage and put them on the counter (loading the OS). This is a loose example, but it works well.

Now to move into OOP: an ingredient is an object, so is a tool (bowl, knife, spoon, etc...). Each one of these has properties (knife= handle_color: black, blade_type: serrated, etc...). And each one has methods/actions that you can perform with them (knife = cut(pepper)).

Now you can take this as far as you want to. For instance, there are green, yellow and red peppers. Each one is a pepper, so you can say "inherit the pepper class" (layman: take everything you know about a pepper and apply it to this specific pepper, pepper has a color attribute, a red pepper is color=red).

You can even separate class from instance (this particular pepper is an instance, whereas on the recipe card it's a class).

So you could make some pseudocode:

class pepper {
    var color
    var spiciness
    var size
}

class redPepper extends pepper {
    construct(){
        $this->color=red
    }
}

class cuttingKnife extends knife{
    construct(){
        $this->blade_type=serated
    }
}

class cookingPot extends pot{
    construct(){
        //We all know what a cooking pot is
    }
}

class stove extends apparatus{
    construct(){
        //We all know what a stove is
    }
}

$knife = new cuttingKnife();
$myPepper = new redPepper();
$pot = new cookingPot();
$stove = new stove();

$knife->cut($myPepper);
$pot->putOn($stove);
$stove->cookOn("high");
$pot->putIn("water");
$pot->putIn($myPepper);

//This will boil a cut pepper

Of course, people won't necessarily understand the pseudocode, but they would understand how to boil something. They would understand the difference between a "pepper" and a "red pepper". I think you can pretty much use this analogy for any computer related thing with some minor tweeks.

  • multithreading: add more burners to the stove and another cook in a single kitchen
  • multicore arch.: add a second kitchen
  • downloading/installing software: go to store, find food, bring home, deposit in storage
  • partitioning a HDD: different cabinets/fridge could be Linux proc system (because it's special).

Etc...

Tim
A: 

A good example is a calculator. Inside a calculator is a circuit board that has connections between its display, buttons, and a logic processor.

The circuit board acts like an abstract class. It provides the plumbing for any calculator built with it. In addition, it has certain interfaces that connect to a display, to an array of buttons, and to a logic processor.

In turn, any display manufactured to work with the circuit board must have a connector that fits the display interface on the circuit board. The same goes for the buttons and the logic processor, the latter likely having a certain arrangement of pins that align with the interface on the circuit board.

A developer using OOD would create an abstract class, CalculatorBase, to define the plumbing between the buttons, the display, and the internal logic. The abstract class would also specify how derivative classes use this plumbing to respond to certain events.

CalculatorBase, however, wouldn't depend on a specific display, a specific set of buttons, or even a specific implementation of logic. Instead, the developer specifies an interface for each, such as ICalculatorDisplay, for example. ICalculatorDisplay would specify how CalculatorBase expects to interact with a display. CalculatorBase would then work with any display that implements ICalculatorDisplay.

Could whomever downvoted this please explain why?
A: 

Interface

An interface is simply a specification. It describes what something MUST do. Nothing more, nothing less. On its own, it is meaningless. It is only useful when someone takes that specification and implements it.

Think of a USB memory stick. It conforms to the specifications of USB. A device communicating with it doesn't need to know or care how the memory stick is going about its job, all it needs to know is that when we ask for data to be written, it is written; conversely, when we ask to read data from it we expect to receive the data.

In computing terms, we use an interface in the same way. If we have:

public interface IUSB
{
    Data Read();
    bool Write();
}

We know that anything implementing this interface has to provide an implementation for Read and Write. How or what it does behind the scenes is of no concern to us. By passing an interface around our code we're not tying ourselves down to specific implementations.

Abstract Class

An Abstract Class simply provides us with a means to put in place specification in a base class that derived types must implement, as well as common code that can be used by all derived types.

I've been trying to thing of a good real-world example and have struggled, so can only really come up with a code example.

Say you wanted to implement an employee hierarchy in your code. So you may have:

public abstract class Employee
{
    public string FirstName { get; protected set; }
    public string LastName { get; protected set; }
    public string Grade { get; protected set; }
    public int Salary { get'
    public abstract void GivePayRise();
}

Every employee has a name and an associated job grade. We can model this in the base class with the first 3 properties. However, giving a bonus may not be a straightforward affair, depending on grade etc. So, we mark this as abstract. Every derived type of Employee (Part-Time, Full-Time, Contract, Consultant) has to implement this.

An implementation may be:

public class FullTimeEmployee : Employee
{
    public void GivePayRise()
    {
        Salary *= 1.1;
    }
}

public class PartTimeEmployee : Employee
{
    public void GivePayRise()
    {
        Salary *= 1;
    }
}

So we want to give a 10% raise to full-time employees, but nothing to part-time ones.

Difficult to give good examples - I generally tend to use interfaces, can't really remember in the past year or so when I've used an abstract class. This could start the whole Abstract Class vs Interface debate, but that's a whole new page.......

Michael
It really frustrates me when someone's answer is voted down without a comment.
Thanks, it is a little pointless. Critisism is great if it's constructive. It's a bit of a strange site really. Once an answer gains momentum, people tend to vote for that and dismiss anything else. Also, people with high reputations will normally get votes, even if there are better answers in the thread. Not using this question as an example, but I've noticed it a few times here and there.Anyhow, I hope you've been able to teach the topics. Good luck!
Michael
+1  A: 

Interface: The buttons of the remote control. Users know how these buttons are supposed to function.

Concrete class: Toshiba RC, Philips RC, JVC RC - what's inside the box is the concrete implementation.

Bozho
A: 

Abstract class: The stencil a tailor uses in order to create a Made to measure garment. While You can't wear the stencil itself it is used to produce suits You can wear - the suits are "derived" from the stencil.

Interface: A dress code.

Dave
A: 

(In some languages, abstract class is used the same way as an interface, so it may be confusing)

A handful of classes that all have a certain common interface is like a handful of words that can fill in the the blank in a sentence. Example:

  • __ has wings
  • Chicken has wings
  • Airbus A320 has wings

However, the classes themselves, while they can all fit the blank in the sentence, do not have any relatioship in between. Chicken is a fowl while Airbus A320 is an aircraft. The only commonality is that they both have something that we call "wings". (You can also say that the true meanings of the "wings" are different in the two situations.)

class IHasWings : public IUnknown
{
public:
    // IUnknown methods: (Inherited)
    // IHasWings methods:
    virtual HRESULT GetWingSpan([out] double* pdblWingSpan) = 0;
    virtual HRESULT IsWingMovable([out] BOOL* pIsMovable) = 0;
    virtual HRESULT IsWingDetachable([out] BOOL* pIsDetachable) = 0;
};

class Chicken : public ... ..., public IHasWings
{
};

class AirbusA320 : public ... ..., public IHasWings
{
};
rwong
A: 

Very simply put, an interface defines how you can talk to me.

Whereas an abstract class could define one of my talents such as playing the guitar. The problem is that "playing guitar," by itself isn't really that useful. But we could use this ability to create a type of person, such as a musician (which we could say is a class).

joshaidan