Ein interface ist erstmal nichts weiter wie eine Vereinbarung: Jede Klasse, die das Interface implementiert, muss die im Interface deklarierten Methoden auch haben. Die im Interface deklarierten Methoden werden erst in der entsprechenden Klasse ausprogrammiert.
Über ein Interface lässt sich das Prinzip der polymorphie umsetzten, wenn zum Beispiel das Prinzip der Mehrfachvererbung nicht unterstützt wird.
Ich hätte hierzu noch eine Ergänzung bzw. weitere Beispiele für ein besseres Verständnis
Der Einsatz des Vererbungsprinzips und das Prinzip der Polymorphie ist auch abhängig von der jeweils eingesetzten Entwicklungsumgebung.
Bei TwinCAT ist es, im Gegensatz zum nativen
CODESYS, möglich das Vererbungsprinzip auf beliebig vielen Ebenen hinweg durchzuführe -> Stichwort "Mehrfachvererbung". Einfaches Beispiel:
Der Errorhandler vererbt seine Methoden zum Erfassen von Fehlerzuständen an die Klasse (Baustein) "Maschine".
Im Baustein "Maschine" können ganz normal die grundlegenden Funktionen der Maschine implementiert werden.
Falls jetzt der Fall auftritt, dass sich die Basismaschine in 2 Ausbaustufen aufteilt, können alle Funktionen auf "Maschine A" und "Maschine B" weiter vererbt werden (Vorteil: Innerhalb von "Maschine A" und "Maschine B" müssen diese Funktionalitäten (Methoden) nicht mehr implementiert werden oder können bei Bedarf um weitere Funktionen erweitert werden können -> Vorteil: Zeitersparnis und keinen "doppelten Code").
Das Gleiche gilt für die nächste Ausbaustufe von Kundenwünschen für "Kunde A" und "Kunde B". Durch die Vererbung hat der Baustein "Kunde A" ebenfalls die Möglichkeit auf die Methoden des Errorhandlers zuzugreifen und diese nutzen zu können.
Die Gefahr von Mehrfachvererbung ist jedoch das Erstellen von sogenannten "Superklassen", die intern eine starke Abhängigkeit besitzen, wodurch sich Änderungen oder Anpassungen sehr aufwendig sind, da es jeden Baustein in der Vererbungshierarchie betrifft.
Im nativen CODESYS hingegen ist das Prinzip der Mehrfachvererbung
nicht erlaubt. CODESYS erlaubt nur eine einzige Vererbungsstufe. Das oben dargestellte Konstrukt lässt sich jedoch durch das Prinzip der Polymorphie nachstellen. Siehe nachfolgendes Beispiel
Im aktuellen Fall besteht nur eine Vererbung zw. "Errorhandler" und "Maschine".
Die danach folgenden Maschinenarten implementieren, im Gegensatz zu obigem Beispiel, eine Schnittstelle und werden innerhalb des Bausteins "Maschine" instanziiert. Der Vorteil (oder auch Nachteil, da die Schnittstelle sehr gut im Voraus überlegt werden muss) ist, dass jede Maschine sich über die Schnittstellenmethode "Control()" ansteuern lässt.
Der Baustein "Maschine" kennt somit nur die Schnittstelle, was dahinter steckt (Maschinentyp) ist dem Baustein in dem Fall egal, er hat nur den Auftrag über die Schnittstellenmethode die Maschine anzusteuern.
Vorteil: Maschinentypen lassen sich relativ einfach austauschen, ändern etc., da alle die gleiche Schnittstelle zum Ansteuern besitzen
Nachteil: Projekte können hierdurch sehr komplex werden
Ein weiteres typisches Beispiel für Polymorphie ist z.B. das Handling von verschiedenen Dateitypen
Die Klasse "Fileparser" hat den einfachen Auftrag, Dateien zu zerlegen und die jeweiligen Informationen zurück zu erhalten. Im aktuellen Fall, kennt sie nur die Schnittstelle "I_FileParse" und deren Methode "parse()", was hinter der Schnittstelle folgt ist ihr nicht bekannt, sie erwartet nur die Abarbeitung der Methode und entsprechende Rückgabewerte.
Im Gegenzug muss jede "Dateityp-Klasse" die Schnittstelle "I_FileParse" mit der Schnittstellenmethode. "parse()" implementieren und diese ausprogrammieren.
Somit lässt sich im Baustein "Fileparser" die Steuerung des Parsing-Vorgang ziemlich einfach umsetzen. Ein weitere Vorteil ist, dass zukünftig weitere Dateitypklassen einfach hinzugefügt werden können.
Mit freundlichen Grüßen
Biiebs