28 November 2007 HowTo, OOP Robert Muehsig

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 ]


Written by Robert Muehsig

Software Developer - from Saxony, Germany - working on primedocs.io. Microsoft MVP & Web Geek.
Other Projects: KnowYourStack.com | ExpensiveMeeting | EinKofferVollerReisen.de