Die objektorientierte Programmierung mit Funktionsbausteinen wird – neben der Möglichkeit zur Erweiterung mithilfe von EXTENDS – auch durch die Möglichkeit der Verwendung von Schnittstellen und Vererbung unterstützt. Dies erfordert dynamisch aufgelöste Methodenaufrufe, auch „virtuelle Funktionsaufrufe“ genannt.
Virtuelle Funktionsaufrufe benötigen etwas mehr Zeit als normale Funktionsaufrufe und werden verwendet, wenn:
oein Aufruf über einen Zeiger auf einen Funktionsbaustein erfolgt (pfub^.method)
oeine Methode einer Schnittstellenvariablen aufgerufen wird (interface1.method)
oeine Methode eine andere Methode desselben Funktionsbausteins aufruft
oein Aufruf über eine Referenz auf einen Funktionsbaustein erfolgt
oVAR_IN_OUT eines Basis-Funktionsbausteintyps einer Instanz eines abgeleiteten Funktionsbausteintyps zugewiesen wird
Virtuelle Funktionsaufrufe ermöglichen, dass derselbe Aufruf in einem Programm-Quellcode während der Laufzeit verschiedene Methoden aufruft.
Weitere Informationen finden Sie unter:
oMethode über die Verwendung von Methoden.
oTHIS-Zeiger über die Verwendung von THIS-Zeigern.
oSUPER-Zeiger über die Verwendung von SUPER-Zeigern.
Gemäß der Norm IEC 61131-3 können Methoden wie normale Funktionen zusätzliche Ausgänge haben. Diese können beim Methodenaufruf gemäß folgender Syntax zugewiesen werden:
<Methode>(in1:=<Wert> |, weitere Eingangszuweisungen, out1 => <Ausgangsvariable 1> | out2 => <Ausgangsvariable 2> | ...weitere Ausgangsvariablen)
Dies bewirkt, dass der Ausgang der Methode – wie im Aufruf definiert – in die lokal deklarierten Ausgangsvariablen geschrieben wird.
Annahme: Funktionsbausteine fub1 und fub2EXTEND Funktionsbaustein fubbase und IMPLEMENT interface1. Methode method1 ist enthalten.
Mögliche Verwendung von Schnittstellen und Methodenaufrufen:
PROGRAM PLC_PRG
VAR_INPUT
b : BOOL;
END_VAR
VAR
pInst : POINTER TO fubbase;
instBase : fubbase;
inst1 : fub1;
inst2 : fub2;
instRef : REFERENCE to fubbase;
END_VAR
IF b THEN
instRef REF= inst1; (* Reference to fub1 *)
pInst := ADR(instBase);
ELSE
instRef REF= inst2; (* Reference to fub2 *)
pInst := ADR(inst1);
END_IF
pInst^.method1(); (* If b is true, fubbase.method1 is called, else fub1.method1 is called *)
instRef.method1(); (* If b is true, fub1.method1 is called, else fub2.method1 is called *)
Annahme: fubbase des obigen Beispiels enthält die 2 Methoden method1 und method2. fub1 überschreibt method2, jedoch nicht method1.
method1 wird, wie im obigen Beispiel dargestellt, aufgerufen.
pInst^.method1(); (* If b is true fubbase.method1 is called, else fub1.method1 is called *)
Beim Aufruf über den THIS -Zeiger siehe THIS-Zeiger.