Was ist der Unterschied zwischen einer Schnittstelle und einer abstrakten Klasse?

Was genau ist der Unterschied zwischen einer Schnittstelle und einer abstrakten Klasse?

Lösung

Schnittstellen

Eine Schnittstelle ist ein Vertrag: Die Person, die die Schnittstelle schreibt, sagt: "Hey, ich akzeptiere, dass die Dinge so aussehen", und die Person, die die Schnittstelle verwendet, sagt: "OK, die Klasse, die ich schreibe, sieht so aus".

Eine Schnittstelle ist eine leere Hülle. Es gibt nur die Signaturen der Methoden, was bedeutet, dass die Methoden keinen Körper haben. Die Schnittstelle kann nichts tun. Es ist nur ein Muster.

Zum Beispiel (Pseudo-Code):

// I say all motor vehicles should look like this:
interface MotorVehicle
{
    void run();

    int getFuel();
}

// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{

    int fuel;

    void run()
    {
        print("Wrroooooooom");
    }

    int getFuel()
    {
        return this.fuel;
    }
}

Die Implementierung einer Schnittstelle verbraucht sehr wenig CPU, da es sich nicht um eine Klasse, sondern nur um eine Reihe von Namen handelt und daher keine teuren Nachschlageoperationen erforderlich sind. Das ist großartig, wenn es darauf ankommt, wie zum Beispiel bei eingebetteten Geräten.


Abstrakte Klassen

Abstrakte Klassen sind, im Gegensatz zu Schnittstellen, Klassen. Ihre Verwendung ist teurer, da bei der Vererbung ein Look-up erforderlich ist.

Abstrakte Klassen sehen ähnlich aus wie Schnittstellen, aber sie haben noch etwas mehr: Man kann ein Verhalten für sie definieren. Es geht eher darum, dass jemand sagt: "Diese Klassen sollten so aussehen, und sie haben das gemeinsam, also füllt die Lücken aus!".

Zum Beispiel:

// I say all motor vehicles should look like this:
abstract class MotorVehicle
{

    int fuel;

    // They ALL have fuel, so lets implement this for everybody.
    int getFuel()
    {
         return this.fuel;
    }

    // That can be very different, force them to provide their
    // own implementation.
    abstract void run();
}

// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
    void run()
    {
        print("Wrroooooooom");
    }
}

Umsetzung

Abstrakte Klassen und Schnittstellen sollen zwar unterschiedliche Konzepte sein, aber die Implementierungen machen diese Aussage manchmal unglaubwürdig. Manchmal sind sie nicht einmal das, wofür man sie hält.

In Java wird diese Regel streng durchgesetzt, während in PHP Schnittstellen abstrakte Klassen sind, die keine Methode deklarieren.

In Python sind abstrakte Klassen eher ein Programmiertrick, den man aus dem ABC-Modul beziehen kann, und verwenden eigentlich Metaklassen und damit Klassen. Und Schnittstellen haben in dieser Sprache mehr mit der Typisierung von Enten zu tun und sind eine Mischung aus Konventionen und speziellen Methoden, die Deskriptoren aufrufen (die __method__methoden).

Wie bei der Programmierung üblich, gibt es Theorie, Praxis und Praxis in einer anderen Sprache :-)

Kommentare (22)

Eine Erklärung finden Sie hier:

Eine abstrakte Klasse ist eine Klasse, die nur teilweise vom Programmierer implementiert Programmierer. Sie kann eine oder mehrere abstrakte Methoden enthalten. Eine abstrakte Methode ist einfach eine Funktionsdefinition, die dazu dient, dem Programmierer mitzuteilen, dass die Methode in einer untergeordneten Klasse implementiert werden muss Klasse implementiert werden muss.

Eine Schnittstelle ist ähnlich wie eine abstrakte Klasse; tatsächlich belegen Schnittstellen den gleichen Namensraum wie Klassen und abstrakte Klassen. Aus diesem Grund können Sie eine Schnittstelle nicht mit demselben Namen definieren wie eine Klasse. Eine Schnittstelle ist eine vollständig abstrakte Klasse; keine ihrer Methoden implementiert, und anstatt eine Klasse Subklasse von ihr ableitet, heißt es, dass sie diese Schnittstelle implementieren.

Wie auch immer, ich finde diese Erklärung von Schnittstellen etwas verwirrend. Eine üblichere Definition ist: *Eine Schnittstelle definiert einen Vertrag, den implementierende Klassen erfüllen müssen. Eine Schnittstellendefinition besteht aus Signaturen von öffentlichen Mitgliedern, ohne implementierenden Code.

Kommentare (3)

Das ist zwar nicht wirklich die Antwort auf die ursprüngliche Frage, aber wenn man den Unterschied zwischen den beiden kennt, kommt man in das Dilemma, wann man was verwenden sollte: https://stackoverflow.com/questions/1231985/when-to-use-interfaces-or-abstract-classes-when-to-use-both

Ich habe zwar nur begrenzte Kenntnisse über OOP, aber die Auffassung, dass Schnittstellen ein Äquivalent zu einem Adjektiv in der Grammatik sind, hat für mich bisher funktioniert (korrigieren Sie mich, wenn diese Methode falsch ist!). Zum Beispiel sind Schnittstellennamen wie Attribute oder Fähigkeiten, die man einer Klasse geben kann, und eine Klasse kann viele von ihnen haben: ISerializable, ICountable, IList, ICacheable, IHappy, ...

Kommentare (0)