Kurz noch ein paar Gedanken von mir dazu:
Ich fürchte, die besten Hinweise gibt es zurzeit nur in einigen englischen Webinaren.
Klassen kannst du auch als Schablone eines Objekts ansehen wobei das Objekt sowohl eine Art erweiterter Datentyp sein kann, wie etwa ein String, der ja jede Menge Funktionen mit sich führt, als auch ein Steuerelement, ein Framework
Das Praktische an Klassen ist die Vererbbarkeit. Nimm an, du benutzt einen PushButton, der auf einen Klick einen anderen Text zeigt.
Das kannst du direkt in einen Pushbutton auf dem Fenster programmieren. Wenn du dies aber häufiger brauchst, entwirfst du einfach eine eigene Unterklasse, die auf einem Button beruht. Dort baust du deine Funktion zum Bildumschalten modular ein, also so, dass eine eigene Eigenschaft “Alt-Text” eingeblendet wird. Intern hast du dann einen Event-Handler für den Action-Event, der den Text umschaltet.
Und statt eines normalen PushButtons lässt du dein Objekt dann auf der neuen Klasse beruhen, weist beim Init den Alt-Text zu und musst dich fortan um nichst mehr kümmern. Fällt dir später eine neue Funktion ein, die so ein Button haben sollte, programmierst du sie in die Klasse, und damit steht sie allen Instanzen zur Verfügung.
Computed Properties kannst du dir auch wie Methoden vorstellen, die bei Zuweisung oder Abfrage einer Eigenschaft automatisch aufgerufen werden. Damit sind dann z. B. Declares möglich die Computed Property startet die Betriebssystemabfrage und gibt den Wert ans Programm weiter oder schickt im umgekehrten Fall den übergebenen Wert ans OS.
Außerdem sind sie fürs Debuggen sehr praktisch, da ihr Inhalt im Debugger angezeigt wird, im Gegensatz zu einer Methode, deren Wert du nur siehst, wenn du sie aufrufst.
Man kann mit C.P.s auch sehr gut Eigenschaften teiltransparent machen. Wenn du irgendein Objekt hast, das bei der Initialisierung eine wie auch immer geartete Kennung erhalten soll, die dann nicht veränderbar sein darf, definierst du einfach diese Eigenschaft, klickst dann auf “Convert to Computed Property” und siehst, dass jetzt einmal die ursprüngliche Property als geschütze Eigenschaft und die Computed da ist, die schon gleich entsprechende Getter und Setter bekommen hat. Wenn du z.B. den Setter entfernst, kann der Wert nicht mehr von außerhalb der Instanz verändert werden.
Shared, wie von Beatrix schon erwähnt, sind Methoden oder Properties, die für die ganze Klasse gelten. Es wäre ja z.B. extremer Overhead, wenn jedes Textfield für sich selbst die interne Kennung als Textfield rumschleppen würde. Stattdessen gibt es eine Klassen-Property, auf die jede Instanz davon zugreift, was jede Menge Speicherplatz und Handling spart.
Und Konvertierungen wie Text.fromCString z.B. kannst du dir als gesharte Methode der Text-Klasse vorstellen du musst dazu ja keine neue Textproperty definieren, sondern rufst die Klasse Text auf und deren Methode fromCString.
Interfaces, finde ich, sind zwei praktische Sachen in einem: Grundsätzlich sehen sie erst mal aus wie einfach leere Methoden, die einer Klasse zugewiesen werden, die dieses Interface erhält. Das wirkt auf den ersten Blick recht unverständlich. Du kannst aber so ein Interface verwenden, um damit Sender und Observer zu defnieren: Ein Observer einer solchen Interfaceklasse meldet sich dann beim Sender an, und der Aufruf der ins Interface integrierten Benachrichtigungsfunktion ruft dann die entsprechende Funktion aller angemeldeten Oberserver auf. Diese behandeln das Ereignis dann jeweils auf die ihnen zugedachte Art. Da findest du in den Programmbeispielen gute Anregungen.
Und, wie Beatrix schon schrieb, du kannst damit verschiedene Klassen mit einer gemeinsamen Steuerung versehen und sozusagen zu einer Meta-Klasse zusammenfassen. Brauchst du z.B. irgendein Objekt, das wahlweise sowohl TCP- als auch Serial-Kommunikation für dich erledigt, kannst du zwar die unterschiedlichen Controls direkt integrieren. Der andere liegt dann brach, und du musst verwalten, welcher Port benutzt wird.
Oder du entwirfst ein Kommunikations-Interface, in dem du die Methoden als Leermethoden anlegst, die du brauchst: Init, Open, Close, Fehlermeldungen
Und wenn du in den Port-Control-Subklassen, die du mit dem Interface verbindest, dann die Leermethoden mit entsprechendem Code füllst, musst du dich fortan nicht mehr drum kümmern, auf welche Art du eigentlich kommunizierst.
Uff, doch gar nicht so kurz geworden. Ich hoffe, das war nicht zu erschlagend