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:
ein Aufruf über einen Zeiger auf einen Funktionsbaustein erfolgt (pfub
^.method)
eine Methode einer Schnittstellenvariablen aufgerufen wird (interface1.method)
eine Methode eine andere Methode desselben Funktionsbausteins aufruft
ein Aufruf über eine Referenz auf einen Funktionsbaustein erfolgt
VAR_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:
Methode über die Verwendung von Methoden.
THIS-Zeiger über die Verwendung von THIS-Zeigern.
SUPER-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 fub2
EXTEND
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.