Das Objektmodell von Perl 6
Um von dieser Seite profitieren zu können, sollten Sie mit den Grundlagen von Perl 6 vertraut sein, und auch ein wenig von Objektorientierung verstehen - wenn Sie wissen, was eine Klasse, ein Objekt und Vererbung ist, reicht das vermutlich schon.
Das Objektmodell von Perl 6 hat nur noch wenige Ähnlichkeiten mit dem von Perl 5, und muß jetzt den Vergleich mit "klassischen" objektorientierten Programmiersprachen nicht mehr scheuen.
Klassen definieren
Klassen werden mit dem class-Schlüsselwort definiert,
das man auf zwei verschiedene Arten verwenden kann. Entweder als erste
Anweisung in einer Datei in der Form class MeineKlasse;, dann
ist der Rest der Datei die Definition der Klasse. Die zweite
Möglichkeit sieht so aus:
class MeineKlasse { # hier kommt die Definition der Klasse } # hier ist die Definition der Klasse zu Ende # und anderer Code kann hier stehen.
Objektvariablen (auch Attribute genannt) werden mit has
anstatt my deklariert, und haben nach dem Sigil (also
$, @, %) noch ein weiteres
Sonderzeichen, ein Ausrufezeichen. Jedes Objekt einer Klasse hat seine
eigene Kopie jeden Attributs. Methoden werden mit method anstatt
sub deklariert:
class Rechteck { has $!breite; has $!hoehe; method flaeche { return $!breite * $!hoehe; } } # benutze den Standardkonstruktor my $r = Rechteck.new(:hoehe(5), :breite(3)); say $r.flaeche; # 15
Attribute sind privat, das heisst Code ausserhalb der Klasse hat keinen Zugriff auf sie. Häufig ist das aber erwünscht, daher gibt es eine einfache Syntax, um sie von aussen mithilfe einer Methode verfügbar zu machen:
class Rechteck { has $.breite; has $.hoehe; method flaeche { # Die Namen der Attribute enthalten immer noch # das Ausrufezeichen return $!breite * $!hoehe; } } my Rechteck $r = Rechteck.new(:breite(5), :hoehe(3)); say $r.flaeche; # 15 say $r.hoehe; # 3 say $r.breite; # 5
Manchmal sollen die Attribute auch von aussen beschreibbar sein, dann fügt
man den Trait is rw an:
class Rechteck { has $.breite is rw; has $.hoehe is rw; method flaeche { return $.breite * $.hoehe; } } my Rechteck $r = Rechteck.new(); $r.breite = 2; $r.hoehe = 5; say $r.flaeche();
Private Methoden funktionieren mit der Syntax
method !meine_methode, und können mit
self!meine_methode aufgerufen werden.
class Auto { has $!motor; has $!gang; method !gang_wechseln ($differenz) { $!gang += $differenz; } ... method beschleunigen { self!gang_wechseln(-1); # hier gas geben self!gang_wechseln(+1); } }
Vererbung
Vererbung wird durch das is-Schlüsselwort
deklariert:
class Form { ... } class Rechteck is Form { ... }
Auch Mehrfachvererbung ist möglich:
class Kraftfahrzeug { ... } class Wasserfahrzeug { ... } class Amphibienfahrzeug is Kraftfahrzeug is Wasserfahrzeug { ... }
(Beispiel aus der Wikipedia)
Vererbung und andere is ...-Traits kann man auch
innerhalb der Klasse schreiben:
class Amphibienfahrzeug { is Kraftfahrzeug; is Wasserfahrzeug; ... }
Klassen erweitern
Wenn man eine Klasse erweitern will, ihr zum Beispiel eine Methode hinzufügen will, kann man das auch ohne Vererbung erreichen:
augment class String { method as_ebcdic { ... } }
Das hat den Vorteil, dass man auch fest eingebaute Datentypen wie String oder Int erweitern kann, und fremder Code, den man einbindet, verwendet automatisch die erweiterte Version. Allerdings können Erweiterungen in einem Teil eines Programms mit Erweiterungen in weit entfernten Programmteilen kollidieren - daher gelten sie als sehr schlechter Stil.
Wenn man versucht, eine Klasse zu erweitern, ohne ein is
also in die Deklaration zu schreiben, bekommt man eine
Fehlermeldung, dass man eine Klasse redeklariert.
Roles
In Perl 6 sind Klassen vor allem dazu da, um "ist-ein"-Beziehungen für Typen zu deklarieren. Für die Wiederverwendbarkeit von Code sind Roles, auf Deutsch Rolle zuständig. Roles sind so etwas wie Interfaces in Java, die Implementierung der Methoden beinhalten.
Genauer gesagt kann eine Role alles enthalten, was eine Klasse auch enthalten kann, nur kann man keine Objekte einer Role erstellen.
role Haustier { has $.halsband; method halsband_loesen { undefine $.halsband; } ... } class Hund is Saeugetier does Haustier { ... }
Wie das Beispiel zeigt, inkorporiert eine Klasse eine Rolle mit dem
Schlüsselwort does.