welcher grund schnittstellen (interfaces) oop

  • von klassen
    zu Vererbung
    und nun bei Schnittstellen.


    ich weiß zwar wie sie erstellt werden:

    PHP
    <span class="syntaxdefault"><br />interface neueSchnittstelle<br /></span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">  public function irgendEineMethode</span><span class="syntaxkeyword">();<br /></span><span class="syntaxdefault">  public function eineAndereMethode</span><span class="syntaxkeyword">();<br />}<br /></span><span class="syntaxdefault"> </span>


    doch kapier ich nicht wo hier die vererbung liegt wenn ich doch nichts im Körper der Methode notieren darf, sie nichts machen kann.


    ich muss ja in jeder Klasse in der ich die Schnittstelle implementiere eigens definieren was die Methode machen soll


    so muss auch jede Klasse welche die Schnittstelle implementiert hat alle Methoden dieser aufrufen


    kann mir jemand die Logik und den 'alltäglichen' Gebrauch von interfaces erklären


    gruß
    peter

  • hallo CyberGirl


    vielen Dank für deine Antwort.


    ich hab mir die Links durchgelesen und bin auf folgendes gestossen:


    Zitat von &quot;http://de.wikipedia.org/wiki/Schnittstelle_%28Programmierung%29&quot;

    Als Ersatz für Mehrfachvererbung eignen sich Schnittstellen allerdings nicht, da sie keine Vererbung von Funktionalität ermöglichen.


    Zitat von &quot;CyberGirl&quot;

    Schittstellen können von anderen Schnittstellen erben


    was ausser deren Methodenköpfe können sie erben?


    und weiters:

    Zitat von &quot;http://www.professionelle-softwareentwicklung-mit-php5.de/oop.foundations.interfaces.html&quot;

    Vererbung von Funktionalität kann stattdessen durch Aggregation und Delegation erreicht werden.


    ich steig jedoch bei Aggregation und Delegation aus :?


    kannst du mir erklären wie ich dadurch eine Funktionalität vererben kann.
    Oder verstehe ich Funktionalität als Methodenkörper (Code)

    PHP
    <span class="syntaxdefault"><br />class Klasse<br /></span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">  public function eineMethode</span><span class="syntaxkeyword">()</span><span class="syntaxdefault">         </span><span class="syntaxcomment">// Methodenkopf<br /></span><span class="syntaxdefault">  </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">    </span><span class="syntaxcomment">// Methodenkörper oder Funtionalität<br /></span><span class="syntaxdefault">  </span><span class="syntaxkeyword">}<br />}<br /></span><span class="syntaxdefault"> </span>


    falsch?


    gruß
    peter

  • Hallo Peter


    Zitat

    was ausser deren Methodenköpfe können sie erben?


    Konstanten werden auch vererbt. Beispiel:

    PHP
    <span class="syntaxhtml"><br /><span class="syntaxdefault"><?php<br /><br />    interface IShape<br />    </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">        const DEFAULT_HEIGHT </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> 100</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">        <br />        function draw</span><span class="syntaxkeyword">();<br /></span><span class="syntaxdefault">    </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">    <br />    interface IShapeEx extends IShape<br />    </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">        function getHeight</span><span class="syntaxkeyword">();<br /></span><span class="syntaxdefault">    </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">    <br />    class Shape implements IShapeEx<br />    </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">        function getHeight</span><span class="syntaxkeyword">()<br /></span><span class="syntaxdefault">        </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">            <br />        </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">        <br />        function draw</span><span class="syntaxkeyword">()<br /></span><span class="syntaxdefault">        </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">            echo </span><span class="syntaxstring">"Default height: "</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">.</span><span class="syntaxdefault"> IShape</span><span class="syntaxkeyword">::</span><span class="syntaxdefault">DEFAULT_HEIGHT</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">        </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">    </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">    <br />    <br />    $s </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> new Shape</span><span class="syntaxkeyword">();<br /></span><span class="syntaxdefault">    $s</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">draw</span><span class="syntaxkeyword">();<br /></span><span class="syntaxdefault">?><br /></span></span>


    Zitat

    kannst du mir erklären wie ich dadurch eine Funktionalität vererben kann.
    Oder verstehe ich Funktionalität als Methodenkörper (Code)


    Es genügt wenn die Methodenköpfe(Signaturen) verebrt werden. Beispiel:


    Dadurch das die Methodenköpfe 'vererbt' werden kann man das Circle Objekt an beide Funtionen übergeben.


    Ich hoffe es hilft Dir etwas weiter.


    LG

  • Hallo CyberGirl,


    danke für deine Informationen!


    Die Vererbung der Konstanten finde ich interessant, und dieses Wissen bringt mir auch so einiges für das Verständnis der Thematik.


    Doch warum schreibst du hier vererbt in Hochkomma?

    Zitat von &quot;CyberGirl&quot;

    Dadurch das die Methodenköpfe 'vererbt' werden kann man das Circle Objekt an beide Funtionen übergeben.


    und wie kann ich die Variablenbezeichnung in der Klammer, in der Signatur verstehen :)

    Zitat von &quot;CyberGirl&quot;
    Code
    function draw(IDrawable $obj)
    {
      //...
    }


    vielen Dank und
    gruß
    peter

  • Hallo Peter,


    Zitat

    Doch warum schreibst du hier vererbt in Hochkomma?


    weil ich die Bezeichnung nicht für so glücklich halte. Wenn man von einer Klasse erbt bekommt man den Code mit und kann die Funktion gleich aufrufen, was bei Schnittstellen nicht der Fall ist.


    Zitat

    und wie kann ich die Variablenbezeichnung in der Klammer, in der Signatur verstehen


    Die Variablenbezeichnung sagt das die übergebene Variable das Interface IDrawable implementieren muß.
    Falls Du z.B. die Funktion mit einer anderen Klasse/Variable aufrufst z.B. echo comp("Hallo");so bekommst Du eine Fehlermeldung:
    Catchable fatal error: Argument 1 passed to comp() must implement interface IComparable, string given, called in C:\xampp\htdocs\projects\Forum\SchnittStellen2.php on line 41 and defined in C:\xampp\htdocs\projects\Forum\SchnittStellen2.php on line 32


    LG

  • Zitat

    für was implementiere ich in Klassen wenn ich in jeder Klasse wieder die Funktionalität definieren muss


    Hmmm, so ganz verstehe ich nicgt was Du meinst. (*grübel*)


    LG

  • ich versteh dass du das nicht verstehst *g*


    ich versuch es noch einmal ..


    wenn ich in einem Interface eine Signatur einer Methode definiere und dann dieses Interface in eine Klasse implementiere muss ich alle Signaturen der geladenen Schnittstelle anführen, diesmal mit Methodenrumpf, da es mir ansonsten einen Fehler wirft.


    ich denke soweit habe ich es richtig verstanden. Oder?


    Nun kann ich eine Instanz der Klasse erzeugen die ich in einem Objekt zur Laufzeit speichere.


    (eigenltich will ich hier gerade testen, ob ich die Begriffe richtig einsetzen kann :))


    so.


    wenn ich nun dieses Interfaces in eine zweite Klasse implentieren, muss ich dort wieder die Methoden angeben und kann theoretisch eine ganz andere Funktionalität programmieren

    Code
    <span class="syntaxdefault"><br />interface Kochen<br /></span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">  public function esGibtReisBaby</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$portionen</span><span class="syntaxkeyword">);<br />}<br /><br /></span><span class="syntaxdefault">class Mama implements Kochen<br /></span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">  public function esGibtReisBaby</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$portionen</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">  </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">    return </span><span class="syntaxstring">'Ich habe '</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">$portionen</span><span class="syntaxkeyword">.</span><span class="syntaxstring">' Portionen leckeren Reis gekocht.'</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">  </span><span class="syntaxkeyword">}<br />}<br /><br /></span><span class="syntaxdefault">class Papa implements Kochen<br /></span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">  public function esGibtReisBaby</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$portionen</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">  </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">    return </span><span class="syntaxstring">'Ich habe  '</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">$portionen</span><span class="syntaxkeyword">.</span><span class="syntaxstring">' Portionen Reis gegessen'</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">  </span><span class="syntaxkeyword">}<br />}<br /><br /></span><span class="syntaxdefault">$meineMama </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> new Mama</span><span class="syntaxkeyword">();<br /></span><span class="syntaxdefault">$meinPapa    </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> new Papa</span><span class="syntaxkeyword">();<br /><br /></span><span class="syntaxdefault">$portionen </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> 8</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">echo $meineMama</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">esGibtReisBaby</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$portionen</span><span class="syntaxkeyword">);<br /></span><span class="syntaxdefault">echo </span><span class="syntaxstring">'<br>'</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">echo $meinPapa</span><span class="syntaxkeyword">-></span><span class="syntaxdefault">esGibtReisBaby</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">$portionen</span><span class="syntaxkeyword">);<br /></span><span class="syntaxdefault"> </span>


    für was habe ich das Interface geschrieben wenn ich doch in jeder Klasse aufs neue Signatur und Rumpf der implementierten Methode definieren muss?



    gruß

  • An deinem Beispiel sieht man auch sehr schön den Nutzen von Interfaces.


    Stell dir vor, du möchtest eine Funktion machen, welcher eine Instanz von Papa oder Mama erwartet, um z.B. den Text von esGibtReisBaby in einer Datenbank speichern soll.
    Hierbei ist es aber egal, ob eine Instanz von Papa oder eine Instanz von Mama übergeben wird. Das einzige, was wichtig ist, ist, dass es in der übergebenen Klasse die Methode esGibtReisBaby gibt.


    Dies kannst du nun schon im Funktionskopf vorraussetzen, indem du einfach mit Type-Hinting angibst, dass die Klasse von Kochen abstammen muss (oder Kochen ist):

    PHP
    <span class="syntaxdefault"></span><span class="syntaxkeyword">function </span><span class="syntaxdefault">speichere_reis</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Kochen $objekt</span><span class="syntaxkeyword">)<br />{<br />    </span><span class="syntaxcomment">// ...<br /></span><span class="syntaxkeyword">} </span><span class="syntaxdefault"></span>
  • Diese Funktion schreibst du außerhalb der Klassen, nicht als Methode.


    Indem du eine Vererbung von Kochen vorraussetzt, kannst du sichergehen, das die benötigte Methode vorhanden ist.
    Du kannst natürlich auch so testen, ob sie vorhanden ist. Im Funktionskopf ist das aber sofort ersichtlich und unter Umständen weniger Code.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!