Abstrakte Klasse vs. Schnittstelle [duplicate]

Lesezeit: 7 Minuten

Ich habe sowohl in SO als auch im Rest des Internets nach einer guten Antwort gesucht, aber ich habe keine gefunden, die ich wirklich verstehe. Ich werde dies auf andere Weise darstellen und hoffe, dass die Antworten auch anderen helfen werden.

Soweit ich weiß, haben die beiden Konzepte die gleichen Regeln, außer dass eine abstrakte Klasse aufgrund der Methodenimplementierungsfähigkeit flexibler ist. Mir ist auch bewusst, dass Sie mehrere Schnittstellen implementieren und nur eine einzige Klasse erweitern können, aber ich bin sicher, dass es mehr Unterschiede gibt als die beiden, die ich erwähnt habe.

Bitte schauen Sie sich die beiden Codeschnipsel an und geben Sie mir ein Beispiel dafür, was ich mit jedem meiner Beispiele tun kann, was dazu führen würde, dass ich das andere verwenden möchte oder nicht.

Abstrakte Klasse

abstract class Foo {
    abstract public function getValue();
    abstract public function setValue($value); 
}


class myObj extends Foo {
    function getValue() {

    }
    function setValue($value) {

    }
}

Schnittstelle

interface Foo {
    public function getValue();
    public function setValue($value);
}

class myObj implements Foo {
    function getValue() {

    }
    function setValue($value) {

    }
}

  • Nehmen wir an, Sie haben bereits eine Klasse Bar inherits Baz und möchte es an eine Methode weitergeben someMethod(Foo $foo). Welche Lösung (Zusammenfassung oder Schnittstelle) könnten Sie verwenden?

    – zerkms

    14. April 2013 um 22:10 Uhr

Benutzer-Avatar
Liuqing Hu

Abstrakt

Abstrakte Klassen konzentrieren sich auf eine Art Ähnlichkeit der Dinge.

Menschen gelten als Typ mammal und als solche nicht als Typ betrachtet werden vehicle.

Schnittstelle

Schnittstellen konzentrieren sich auf die Zusammenstellung ähnlicher Funktionen.

Zum Beispiel: Du bist ein Mensch und hast einen Typ mammal. Wenn Sie fliegen möchten, müssen Sie a implementieren flying Interface. Wenn Sie beim Fliegen schießen wollen, dann müssen Sie das auch umsetzen gun Interface.

Siehe die folgenden Beispiele:

abstract class Mammal {
      protected $age_;
      //below are functions I think all mammals will have,including people
      abstract public function setAge($age);
      abstract public function getAge();
      abstract public function eat($food);
}
class Person extends Mammal {
      protected $job_; //Person's feature
      public function setAge($age){
        $this->age_ = $age;
      }

      public function getAge(){
        return $this->age_;
      }

      public function eat($food){
        echo 'I eat ' ,$food ,'today';
      }

      //People only attribute
      public function setJob($job){
         $this->job_ = $job;
      }
      public function getJob(){
         echo 'My job is ' , $this->job_;
      }

}

//Now a person wants to fly, but they are typically not able to do so.
//So we implement an interface
interface Plane{
  public function Fly(); 
}

//I also want shoot enemy
interface Gun{
  public function shoot();
}

class Person2 extends Mammal implements Plane,Gun{

      protected $job_;//Person feature
      public function setAge($age){
        $this->age_ = $age;
      }
      public function getAge(){
        return $this->age_;
      }
      public function eat($food){
        echo '<br/>I eat ' ,$food ,' today<br/>';
      }
      //Only a person has this feature.
      public function setJob($job){
         $this->job_ = $job;
      }
      public function getJob(){
         echo 'My job is ' , $this->job_;
      }

      //-----------------------------------------
      //below implementations from interfaces function. (features that humans do not have).
      //Person implements from other class
      public function fly(){
        echo '<br/>I use plane,so I can fly<br/>';
      }
      public function shoot(){
        echo 'I use gun,so I can shoot<br/>';
      }
}

$People = new Person();
echo '<pre>';
print_r( get_class_methods('People'));
echo '</pre>';

echo '<pre>';
print_r( get_class_methods('People2'));
echo '</pre>';

$People2 = new Person2();
$People2->setAge(24);
echo $People2->getAge();
$People2->eat('egg');
$People2->setJob('PHP devepop');
echo $People2->getJob();

$People2->fly();
$People2->shoot();

  • Beste Analogie aller Zeiten. Ich werde dies verwenden, um anderen abstrakte Klassen und Schnittstellen zu erklären. +1

    – Aggregat1166877

    6. Februar 2014 um 14:31 Uhr

  • @LiuqingHu @ Super Art, Dinge zu erklären, können Sie mir bitte helfen, Ihre Schnittstellenklasse zu verwenden, mit etwas mehr Beispiel.

    – jsdunija

    7. Februar 2014 um 7:09 Uhr

  • class People2 extends Mammalian implements Plane,Gun — vielleicht ist es nur eine Frage der Sprachbarriere, aber das klingt verrückt.

    – Dan Lugg

    18. Februar 2014 um 15:21 Uhr

  • Spaß … aber verrückt 🙂

    – PeeHaa

    18. Februar 2014 um 15:22 Uhr

  • @Vladd deshalb implementiert es dafür keine Schnittstellen. Tolle Erklärung Liu!

    – Lukas Lukas

    4. Januar 2015 um 18:55 Uhr

Benutzer-Avatar
MatRt

Um die Idee zusammenzufassen (global, nicht im Detail):

inheritance

ist die Vorstellung zu extend from something, und fügen Sie optional ein neues Feature hinzu oder überschreiben Sie ein vorhandenes Feature (um es anders zu machen). Aber mit der Vererbung teilen Sie einen großen Teil des Codes mit dem übergeordneten Element. Sie sind ein Elternteil + einige andere Dinge.

interface

repräsentiert einige Fähigkeiten (wir sagen, eine Klasse ist umsetzen eine Schnittstelle zu sagt, dass es diese Fähigkeiten hat). Eine Schnittstelle kann von 2 Klassen implementiert werden, die völlig unterschiedlich sind und ihren Code nicht teilen (mit Ausnahme der Methoden, die sie implementieren). Wenn A und B die Schnittstelle C implementieren, ist A kein B und B kein A.

Und einer der Gründe dafür interface ist es in der Tat, Programmierern zu ermöglichen, dasselbe zu tun, was sie mit Mehrfachvererbung tun könnten, jedoch ohne Probleme mit Mehrfachvererbung.

Dieser Begriff wird in einigen Programmiersprachen wie JAVA, PHP … verwendet.

  • Diese beiden Ideen konzentrieren sich also zum größten Teil eher auf Prinzipien als auf tatsächliche Implementierungsdetails. In meinem Beispielcode wären die beiden Vorgehensweisen genau gleich, da der Code nichts bedeutet und zu mehrdeutig ist, um zu bestimmen, welche Implementierung besser geeignet wäre. Liege ich mit meiner Überlegung richtig?

    – Nathanjosia

    12. April 2013 um 5:09 Uhr

  • Welche Implementierung besser geeignet ist, hängt von Ihren Anforderungen ab. Wenn Sie eine abstrakte Funktion erstellen und nichts an der abstrakten Klasse tun, nur um in einer 1-Ebene zu erben, wird die Schnittstelle besser, da Sie eine Schnittstelle aus jeder Klasse (jeder Art von Objekt) implementieren können. Wenn Sie jedoch mehrere Vererbungsebenen in Ihren Klassen haben und eine übergeordnete Version wiederverwenden müssen, ist es besser, die abstrakte Klasse zu verwenden.

    – MatRt

    14. April 2013 um 22:13 Uhr

  • Die beste Analogie aller Zeiten finden Sie in der Antwort unten.

    – Stypon

    26. Februar 2014 um 17:26 Uhr

Kurz gesagt, Schnittstelle ist es, eine Reihe von Funktionen zu standardisieren,während abstrakte Klasse ist es, ein Grundgerüst zu definieren, von dem Klassen abgeleitet werden können.

  • Wäre es richtig zu sagen, dass abstrakte Klassen mit abstrakten Methoden erfordert Nachkommenklassen, um diese Methoden zu definieren (oder zumindest für alle abstrakten Methoden, die irgendwo in sich selbst oder ihren Vorfahren implementiert werden)?

    – ahnbizcad

    3. August 2015 um 20:51 Uhr


  • Hmm in Verbindung mit der Antwort von Liuqing Hu macht das alles jetzt Sinn 8)

    – Andreas

    10. Februar 2016 um 18:24 Uhr

  • Ich mag diese Antwort. Einfacher gesagt erzwingen sowohl Schnittstellen als auch abstrakte Klassen EIGENSCHAFTEN oder ATTRIBUTE für eine Klasse. Der Unterschied besteht darin, dass Schnittstellen zu 100 % abstrakt sind und daher von einigen als Verträge bezeichnet werden. (Denken Sie eine Sekunde darüber nach, Sie erzwingen, wie eine Klasse funktioniert.)

    – Benutzer1889992

    29. März 2016 um 12:02 Uhr


Benutzer-Avatar
Mohammed Tarek

Ich habe darüber schon früher nachgedacht, und das Beste, was ich daraus schließen konnte, war das Schnittstellen sind eine logisch bequeme Abstraktion einer reinen abstrakten Klasse (c++).

Warum Sie Schnittstellen abstrakten Klassen vorziehen würden, zitiere ich (eine C++-Quelle aber die Konzepte sind die gleichen):

Beachten Sie, dass die Versuchung groß ist, reinen abstrakten Basisklassen konkrete Elementfunktionen und Daten hinzuzufügen. Dem muss widerstanden werden, im Allgemeinen ist es ein Zeichen dafür, dass die Schnittstelle nicht gut kalkuliert ist. Daten und konkrete Elementfunktionen implizieren tendenziell eine bestimmte Implementierung und können als solche von der Schnittstelle erben, sollten aber nicht diese Schnittstelle sein. Wenn stattdessen eine gewisse Gemeinsamkeit zwischen konkreten Klassen besteht, funktioniert die Erstellung einer abstrakten Klasse, die ihre Schnittstelle von der reinen abstrakten Klasse erbt und die gemeinsamen Daten und Elementfunktionen der konkreten Klassen definiert, gut.

Die Sache ist, wenn man Schnittstellen verwendet, fällt einem als erstes ein Entkopplung. Bei der Verwendung einer Schnittstelle sind der Benutzer und die implementierende Klasse vollständig entkoppelt. Gleiches gilt für die Verwendung von a reine abstrakte Klasse das ist im Grunde eine Schnittstelle.

1334730cookie-checkAbstrakte Klasse vs. Schnittstelle [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy