26.02.2014 Aufrufe

Linux-Magazin Clean Linux (Vorschau)

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

Abbildung 4: Wie bei Java darf die »main()«-Funktion auch Teil einer Klasse<br />

sein, sofern sie dort als »static« markiert ist.<br />

dieses Konzept als Events, Java-Programmierer<br />

nutzen Event-Listener. In Listing<br />

7 definiert die Klasse »Auto« zunächst<br />

mit dem Schlüsselwort »signal« ein neues<br />

Signal namens »anlassen«. Dieses wiederum<br />

ist nichts anderes als eine Methode<br />

ohne Rumpf.<br />

Sobald er ein Objekt der Klasse angelegt<br />

hat, kann der Programmierer mit »connect()«<br />

eine oder mehrere Methoden<br />

für das Signal registrieren. Das Listing<br />

meldet einfach nur eine anonyme Methode<br />

an. Es genügt dann der Aufruf von<br />

»anlassen()«, um das Signal auszulösen<br />

und so die anonyme Methode zu wecken.<br />

»anlassen()« verlangt dabei nach<br />

einem String, den Vala wiederum an alle<br />

registrierten Methoden weiterleitet. Im<br />

Beispiel nimmt die anonyme Methode<br />

diesen String als »a« entgegen. Zusätzlich<br />

bekommen alle registrierten Methoden<br />

immer auch das Objekt übergeben, das<br />

das Signal gesendet hat.<br />

Schreibblockade<br />

In Vala lassen sich Methoden nicht überschreiben,<br />

Entwickler dürfen folglich<br />

keine Methoden mit gleichen Namen und<br />

unterschiedlichen Parametern definieren.<br />

Bei den Konstruktoren helfen benannte<br />

Konstruktoren aus. Dabei hängt man einfach<br />

wie in Listing 8 einen Punkt mit<br />

einem Namen an.<br />

Abgeleitete Klassen dürfen die Methoden<br />

der Oberklasse sehr wohl überschreiben,<br />

im Listing zeigt dies der »Ferrari«. Der<br />

Code in der letzten Zeile ruft dann jedoch<br />

»starten()« von »Auto« auf. Das lässt sich<br />

verhindern, indem der Entwickler wie in<br />

Listing 9 die Methode<br />

der Oberklasse zu einer<br />

virtuellen macht<br />

und in der Subklasse<br />

der Methode ein<br />

»override« voranstellt.<br />

Soll die Methode in<br />

der Subklasse eine andere<br />

Signatur besitzen,<br />

stellt er ihr ein »new«<br />

voran – wie im Listing<br />

beim »BMW«.<br />

Wie C# und Java kennt<br />

Vala Interfaces. Sie geben<br />

Attribute und Methoden<br />

vor, die eine<br />

Klasse implementieren<br />

muss. Ein Beispiel zeigt Listing 10: Das<br />

»abstract« vor »starten()« weist darauf<br />

hin, dass eine Klasse die Implementierung<br />

übernimmt.<br />

Im Gegensatz zu anderen Sprachen dürfen<br />

Interfaces aber auch eine bestimmte<br />

Implementierung vorgeben (Stichwort:<br />

Mixin). Während Klassen immer nur<br />

von einer Oberklasse erben, dürfen sie<br />

beliebig viele Interfaces implementieren.<br />

Interfaces wiederum dürfen nicht von anderen<br />

Interfaces erben, wohl aber mehrere<br />

Kolleginnen und eine andere Klasse<br />

als Voraussetzung nennen. Im Beispiel<br />

gibt »Auto« die Klasse »GLib.Object« vor,<br />

von der »Ferrari« zwingend erben muss.<br />

Wechselbalg<br />

Eine Garage soll sowohl einen Ferrari als<br />

auch einen BMW aufnehmen können.<br />

Genau dafür bieten sich Generics an: Der<br />

Entwickler legt eine Klasse »Garage« an,<br />

lässt aber wie in Listing 11 den Typ der<br />

zu speichernden Daten zunächst offen.<br />

»A« dient dort als Platzhalter für einen<br />

beliebigen Datentyp. Beim Erstellen eines<br />

konkreten »Garage«-Objekts gibt er dann<br />

den jeweils gewünschten an:<br />

Garage gf = new Garage();<br />

Die neue Garage »gf« speichert damit<br />

Objekte vom Typ »Ferrari« und ist vom<br />

Typ »Garage«. Generics eignen<br />

sich vor allem für Listen und Mengen.<br />

Vala bietet in der Gee-Bibliothek ein paar<br />

häufig benötigte Datenstrukturen an, darunter<br />

etwa mit »Map« ein assoziatives<br />

Array beziehungsweise Dictionary<br />

[5]. Gee ist allerdings eine separate Bibliothek,<br />

Nutzer des fertigen Programms<br />

müssen sie folglich auf ihrem System<br />

nachinstallieren. Da sie die meisten Distributionen<br />

vorhalten, genügt ein Griff<br />

zum Paketmanager, das entsprechende<br />

Paket heißt meist »libgee«.<br />

Namenstag<br />

Mit Namespaces darf man zusammengehörenden<br />

Codeteilen einen Namen geben.<br />

Der Zugriff auf seine Klassen und<br />

Funktionen erfolgt dann über die Punktnotation:<br />

namespace Autos {<br />

class BMW { [...] }<br />

class VW { [...] }<br />

}<br />

[...]<br />

Autos.BMW meinauto = Autos.BMW();<br />

Auch die einzelnen Vala-Bibliotheken<br />

nutzen ausgiebig Namespaces. So besit-<br />

Listing 6: Alternative<br />

Klassendefinition<br />

01 public class Auto : GLib.Object {<br />

02 <br />

03 public string farbe { get; set; }<br />

04 <br />

05 public Auto(string f) {<br />

06 Object(farbe: f);<br />

07 }<br />

08 <br />

09 ~Auto() {print("verschrottet");}<br />

10 <br />

11 public void lackieren(string f) {<br />

12 this.farbe = f;<br />

13 }<br />

14 <br />

15 construct {<br />

16 print("Willkommen");<br />

17 }<br />

18 }<br />

Listing 7: Signalbehandlung<br />

01 class Auto : GLib.Object {<br />

02 public signal void anlassen(string a);<br />

03 }<br />

04 <br />

05 [...]<br />

06 <br />

07 // Signal‐Handler registrieren:<br />

08 Auto vw = new Auto();<br />

09 vw.anlassen.connect( (sender, a) => {print(a);} );<br />

10 <br />

11 vw.anlassen("Brumm"); // Signal auslösen<br />

Vala 09/2013<br />

Programmieren<br />

www.linux-magazin.de<br />

95

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!