How can you explain the difference between an inte

2019-03-10 02:10发布

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.

9条回答
混吃等死
2楼-- · 2019-03-10 02:41

(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
{
};
查看更多
欢心
3楼-- · 2019-03-10 02:45

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

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; protected set; }
    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.......

查看更多
Fickle 薄情
4楼-- · 2019-03-10 02:45

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.

查看更多
爷、活的狠高调
5楼-- · 2019-03-10 02:47

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.

查看更多
Luminary・发光体
6楼-- · 2019-03-10 02:48

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...

查看更多
Explosion°爆炸
7楼-- · 2019-03-10 02:52

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.

查看更多
登录 后发表回答