HowTo: Interfaces/Schnittstellen verstehen – mal auf simple Art und Weise

In dem HowTo geht es um ein sehr simples Thema, womit aber besonders Einsteiger in der Programmierung Probleme haben: Wozu sind Schnittstellen/Interfaces gut? Man kann doch auch genauso gut von einer Klasse erben – also wozu der Spaß und wo kann man das sinnvoll einsetzen?

Wir machen das sehr kurz und schmerzlos an einem “praktischen” Beispiel aus der Natur ;)

In unserem sehr einfachen Beispiel wollen wir bestimmte Klasse (Train, Car, Human) erstellen welche beweglich sind (IMovable) – jedoch bewegt sich ja alles auf eine unterschiedliche Art und Weise, daher ist das unsere Schnittstelle.
Jetzt gehen wir mal davon aus, dass es einen Gott (God) gibt, dann kann der auch ohne Probleme ein bewegliches Objekt “anstupsen”. Genau das wollen wir jetzt implementieren – wie gesagt, sehr praxisnah ;)

Konsolenprojekt Struktur:

image

Das wichtigste ist erstmal unser Interface “IMovable” (Schnittstellen werden in .NET immer mit einem I davor geschrieben):

    public interface IMovable
    {
        void Move();
    }

Die Schnittstelle legt nur fest, welche Methoden, Eigenschaften oder Events etwas hat – wie dies jeweils implementiert ist entscheidet dann die Klasse.

    public class Human : IMovable
    {
        #region IMovable Member

        public void Move()
        {
            Console.WriteLine("Der Mensch macht einen Schritt vor.");
        }

        #endregion
    }

Unser Mensch kann einen Schritt vor dem anderen machen – unser Zug fährt zum nächsten Bahnhof und unser Auto nur zur nächsten Ampel. In den einzelnen Klassen kann man nun die Methode implementieren wie man mag – wichtig ist nur, dass die Signatur (also Rückgabetyp, Parameter & Name) gleich bleibt.

Jetzt wollen wir unseren Gott implementieren, welcher Objekte “anstupsen” kann. Allerdings wollen wir nicht X Methoden erstellen, die in dieser Form sind “MoveObject(Human human)”, weil wir noch nicht genau wissen, was sonst noch für bewegliche Klassen hinzukommen.

Hier kommt jetzt unser Interface zum Einsatz:

    public class God
    {
        public static void MoveObject(IMovable item)
        {
            Console.WriteLine("Ein bewegliches Objekt wird bewegt...");
            item.Move();
        }
    }

Die Methode “MoveObject” nimmt einfach “irgendwas” was “IMovable” impementiert – egal ob es ein Auto, Zug oder Mensch ist.
Allerdings kann man in dieser Version jetzt nur auf die Methoden, Eigenschaften etc. zugreifen, welche in der Schnittstelle definiert sind:

image

Wenn man jetzt beim Auto noch eine spezial Methode implementiert hat, welche man unbedingt dort aufrufen will, muss man casten und über GetType prüfen, ob das Objekt von Typ “Car” ist – aber das geht zu weit und ist jetzt erstmal kein Thema hier.

Der Hauptvorteil jetzt liegt darin, dass unsere “MoveObject” Methode keine Ahnung haben braucht, was “item” einfach ist – hauptsache es ist beweglich. Was beweglich bei diesem Objekt heisst, ist dieser Methode egal.

Unser kleines Programm testen:

    class Program
    {
        static void Main(string[] args)
        {
            Car BMW = new Car();
            Train ICE = new Train();
            Human Robert = new Human();

            God.MoveObject(BMW);
            God.MoveObject(ICE);
            God.MoveObject(Robert);

            Console.ReadLine();
        }
    }

Wir haben ein BMW, ein ICE und mich – und diese bewegt unser Gott natürlich. Resultat:

image

So – alle unsere 3 Objekte bewegen sich anders und es wird angezeigt. Jetzt kann man noch weitere Klassen hinzufügen, welche ebenfalls “IMovable” implementieren und wir brauchen die God.MoveObject Methode nicht anpassen.

Olé ;)

PS: Nein, ich bin nicht religös, brauchte aber ein einfaches Beispiel.

[ Download Source Code ]


Kick It auf dotnet-kicks.de
Wenn dir der Blogpost gefallen hat, dann hinterlasse doch einen Kommentar. Wenn du auf dem Laufenden bleiben willst, abonniere unseren RSS Feed oder folge uns auf Twitter.

About the author

Written by Robert Mühsig

Robert Mühsig (@robert0muehsig) ist Webentwickler und beschäftigt sich mit Web-Frameworks (vor allem dem ASP.NET MVC Framework) und scheut sich auch nicht vor Javascript. Ansonsten bloggt er über all jene Probleme, die ihm über den Weg laufen. Seit 2008 ist er Microsoft MVP für ASP.NET und er arbeitet bei der T-Systems Multimedia Solutions GmbH in Dresden. Treffen kann man ihn online via Twitter (@robert0muehsig) oder dieser Seite oder bei der .NET User Group Dresden.

23 Responses

  1. Schönes Beispiel! :-)

    Reply
  2. Sehr schönes und einfaches Beispiel.
    Das werde ich sicherlich nutzen, und den Link weitergeben, wenn mich wieder einer fragt was das mit den Schnittstellen auf sich hat.

    Gott sei Dank !!
    Und dir natürlich :-)

    Reply
  3. Cooles HowTo , hat in 2 Minuten alle Fragen beantwortet !
    Danke !

    Reply
  4. Danke fürs Beispiel … kurz und verständlich
    Du hast geschafft was unser Lehrer in 2 h nicht geschafft hat ;)

    Reply
  5. Sehr gutes Beispiel.

    Übrigens, Gott schubst einen nur an, wenn man das möchte. Try it!

    Reply
  6. guter artikel, sourcecode kann allerdings nicht downgeloaded werden: 404

    Reply
  7. Vielen Dank für den Hinweis – ist jetzt gefixt :)

    Reply
  8. Heyho..danke für die schnelle Erklärung..
    Echt gut gelungen das ganze, schnell zu lernen und man kenn sich aus;)

    gratz von meiner seite

    Reply
  9. Ich habe den Sinn von Interfaces über Jahre nicht verstanden (auch nicht weiter nachgeforscht) und sie daher auch nie angewendet. Erst durch dieses Beispiel hier ist mir der praktische Nutzen bewusst geworden. :-)

    Reply
  10. Hallo!

    Also erstmal, großes Lob für diese simple und einleuchtende Erklärung =)

    Nun ein ganz kleiner Vergesserungsvorschlag:
    Du hattest geschrieben:
    [..]Die Methode “MoveObject” nimmt einfach “irgendwas” was von “IMovable” abgeleitet ist – egal ob es ein Auto, Zug oder Mensch ist. [...]

    Richtiger wäre wenn du schreiben würdest, dass die Methode MoveObject einfach "irgendwas" nimmt was IMovable implementiert. Nicht was davon abgeleitet ist.
    Da kann man Ärger für bekommen ;)

    Ansonsten könntest du Movable noch Moveable bennen =)
    *klugscheißen off*

    Sorry, ist nicht blöd gemeint oder so aber wollen ja nicht dass sich das alle "nicht ganz richtig" merken.

    Sooo.. aber wie gesagt, tolle arbeit.
    Würde ich jedem empfehlen der mit Interfaces noch auf Kriegsfuß steht bzw. nicht weiß wozu das Ganze =)

    Reply
  11. Das mit dem abgeleitet/implementiert habe ich geändert – danke für die Info.

    Bei dem "Movable": dict.cc sagt mir das beide Varianten gehen (und ich auch zu Faul bin diese jetzt umzubenennen) ;)

    Reply
  12. top!

    Reply
  13. Erstmal schönes Beispiel, aber entweder bin ich lernresistent oder ich brauch wirklich mal ein Bsp. aus der Praxis. Weil ich seh den Vorteil immernoch nicht.

    Wieso werf ich das Interface und GodKlasse nicht einfach weg und mache in der Main:

    BMW.Move();
    Human.Move();
    etc.

    Spart mir Programmieraufwand und auch hier kann ja problemlos ein neues Objekt hinzukommen, zBsp. ein Flugzeug. Ein Objekt davon wird in der Main ja sowieso erstellt:

    Plane a380 = new Plane();

    und ob ich dann:

    a380.Move();

    oder

    God.MoveObject(a380);

    mache ist doch egal ?
    Das man die God-Klasse nicht ändern muss hab ich ja verstanden, ich frage mich nur immer, wozu brauch ich sowas überhaupt ? Wenn ich das Flugzeug, Auto, Mensch Objekt ohnehin erzeuge, wieso rufe ich die Methode nicht direkt darauf auf sondern über Umwege ? :(

    Reply
  14. Hier hast du mal ein Beispiel aus der Praxis, ist allerdings durch das Thema “Dependency Injection” schon etwas komplexer: http://code-inside.de/blog/2010/06/27/howto-alle-implementationen-vom-interface-x-ber-castle-windsor-per-di-auflsen/

    Reply
  15. Ich würde die Objekte so erzeugen

    IMovable BMW = new Car();
    IMovable ICE = new Train();
    IMovable Robert = new Human();

    um dem Gedanken des Interfaces gerecht zu werden.
    Am Ende möchte ich ja nur die Eigenschaften und Methoden nutzen, die durch das Interface vorgegeben sind.

    Oder gibt es einen besonderen Grund, es nicht so umzusetzen?

    Reply
  16. Hallo,

    Wirklich ein gutes Beispiel. Was du aber noch hättest erwähnen können, ist der Grund, weshalb man nicht einfach eine abstrakte Klasse benutzt. Damit könnte man nämlich das genau gleiche erreichen.

    Reply
  17. Toll. :-)

    Ein sehr schönes und gut verständliches Beispiel.

    Hat mir weitergeholfen, vielen Dank!

    Reply
  18. Top. Danke für die “realitätsnahe” Erklärung.

    Reply

Comment on this post

Letzte Posts

  • Carriage Return / Neue Zeile in Textareas

    Eine kleine Aufgabe: Jede neue Textzeile (Carriage Return/Wenn man Enter drückt ) in einer Textarea soll ein Element in einer Auflistung sein – wie mach ich das jetzt am einfachsten? Eigentlich ein grundlegendes Element im Web und der Nutzer macht bewusst Absätze – daher wäre es nur gerecht, wenn man das auch entsprechend würdigt. Kleine ...

  • image.png
    Doom, Quake, Wolfenstein & co. Source Code auf GitHub

    id Software, die Macher von Doom, Quake, Wolfenstein & co., stellen regelmäßig ihre älteren Spieltitle als Open Source zur Verfügung. Das Ganze runterzuladen fand ich bisher immer recht mühselig, allerdings gibt es seit kurzer Zeit die Sourcen auch auf GitHub. Darunter Spiele wie Doom 3, Quake 3, Wolfenstein für iOS. Wer also schon immer mal ...

  • image.png
    Twitter Bootstrap 2.0 released & “Release Präsentation”

    Wie bereits vom Twitter Bootstrap Team angekündigt wurde offiziel die Version 2.0 des UI Toolskits “Twitter Bootstrap” veröffentlich. Zudem wurden die Slides, welche bei der Release Party gezeigt wurden auch veröffentlicht: Downloads finden sich auf der Twitter Bootstrap Seite auf GitHub. Wenn dir der Blogpost gefallen hat, dann hinterlasse doch einen Kommentar. Wenn du auf ...

  • image.png
    Javascript zu Dart Translator

    Dart, Google Javascript Alternative, wurde vor ein paar Monaten vorgestellt und die Webentwickler Szene ist noch etwas gespalten, ob Dart nun überflüssig ist oder einfach nur cool und längst überfällig ist. Um die Sprache näher zu erläutern hat Google die grundlegenden Javascript Basics nach Dart übersetzt. Das Ergebnis ist der “Translator”. Der Name mag momentan ...

  • Twitter Bootstrap 2.0–“Beta”

    Twitter Bootstrap, ein UI-Toolkit für Web-Applikationen von Twitter, erscheint (wie bereits berichtet) demnächst in der Version 2.0. Der offizielle Release ist am 31. Januar, allerdings beginnt jetzt laut Mark Otto (einer der Hauptentwickler von Twitter Bootstrap) die intensive Test-Phase. Das heisst, das es nun offiziel auch die 2.0 Dokumentation online gibt. Im Vergleich zur aktuellen ...

Support us!

Facebook