PBXB64 OOP & Klassen

OOP & Klassen Standard

Vollständige objektorientierte Programmierung with CLASS, INTERFACE, METHOD, PROPERTY, EVENTS FROM, EVENTS END, RAISEEVENT, IMPLEMENTS, and WITH. Multi-Subscriber-Event-Dispatch, Interface-Vererbung, and Property-Accessoren. Alles unterstützt von echtem Vtable- und Event-Helper-Runtime-Code.

CLASS with METHOD and PROPERTY

Klassen-Definition und -Verwendung
#COMPILE EXE #DIM ALL CLASS MyClass INSTANCE count AS LONG CLASS METHOD Create() ' constructor, runs when the object is created count = 0 END METHOD INTERFACE IMyClass INHERIT IUNKNOWN METHOD Increment() AS LONG count = count + 1 METHOD = count END METHOD PROPERTY GET Counter() AS LONG PROPERTY = count END PROPERTY END INTERFACE END CLASS FUNCTION PBMAIN() AS LONG LOCAL obj AS IMyClass LET obj = CLASS "MyClass" obj.Increment() obj.Increment() PRINT "Count: "; obj.Counter ' 2 FUNCTION = 0 END FUNCTION

CLASS definiert einen Typ mit INSTANCE-Variablen und einem INTERFACE, das die METHOD- und PROPERTY-Member enthält. Objekte werden mit LET obj = CLASS "name" erzeugt; CLASS METHOD Create() dient als Konstruktor. Member werden per Punktnotation aufgerufen (Methoden mit oder ohne Klammern), mit echtem Vtable-Dispatch.

EVENTS FROM / EVENTS END / RAISEEVENT

Multi-Subscriber-Events
#COMPILE EXE #DIM ALL INTERFACE IEvents ' event interface: the shared contract INHERIT IUNKNOWN METHOD MyEvent(BYVAL iValue AS LONG) END INTERFACE CLASS Listener1 AS EVENT ' event sinks are marked AS EVENT INTERFACE IEvents INHERIT IUNKNOWN AS EVENT METHOD MyEvent(BYVAL iValue AS LONG) PRINT "Listener1 got: "; iValue END METHOD END INTERFACE END CLASS CLASS Listener2 AS EVENT INTERFACE IEvents INHERIT IUNKNOWN AS EVENT METHOD MyEvent(BYVAL iValue AS LONG) PRINT "Listener2 got: "; iValue END METHOD END INTERFACE END CLASS CLASS EventSource INTERFACE IEvents ' redeclared inside the source (empty bodies) INHERIT IUNKNOWN METHOD MyEvent(BYVAL iValue AS LONG) END METHOD END INTERFACE INTERFACE ISource INHERIT IUNKNOWN METHOD Trigger() RAISEEVENT IEvents.MyEvent(42) END METHOD END INTERFACE EVENT SOURCE IEvents ' this class raises IEvents events END CLASS FUNCTION PBMAIN() AS LONG LOCAL src AS ISource LOCAL l1 AS IEvents LOCAL l2 AS IEvents LET src = CLASS "EventSource" LET l1 = CLASS "Listener1" LET l2 = CLASS "Listener2" EVENTS FROM src CALL l1 ' subscribe the listeners EVENTS FROM src CALL l2 src.Trigger() ' raises MyEvent(42) EVENTS END l1 ' unsubscribe EVENTS END l2 FUNCTION = 0 END FUNCTION

Das Event-Interface wird einmal auf Modulebene deklariert. Die Quellklasse deklariert es verschachtelt erneut, ergänzt EVENT SOURCE und löst Ereignisse mit RAISEEVENT IEvents.Method(args) aus. Listener-Klassen werden mit AS EVENT deklariert. EVENTS FROM meldet einen Listener an, EVENTS END meldet ihn ab; RAISEEVENT verteilt an alle registrierten Listener über Runtime-Helfer (bestof_events_from, bestof_events_end, bestof_raiseevent_0..6). Vollständiger Regressionstest: test_class_events_multi.pb.

WITH - Block-Weitiges Member-Zugriff

WITH-Block für Kurzzugriff
#COMPILE EXE #DIM ALL TYPE Counter count AS LONG label AS STRING END TYPE FUNCTION PBMAIN() AS LONG LOCAL c AS Counter WITH c .label = "clicks" .count = 0 .count = .count + 1 .count = .count + 1 PRINT .label; ": "; .count ' clicks: 2 END WITH FUNCTION = 0 END FUNCTION

WITH speichert die Variablen-Referenz und expandiert .field-Präfixe im gesamten Block, sodass der Variablenname nicht wiederholt werden muss. Es funktioniert mit TYPE-Variablen; für Interface-Objekte wird der Objektname verwendet. Die Variable wird in fn->with_var gespeichert und von den Ausdrucks- und Deklarations-Parsern genutzt.

Zurück zur Feature-Liste