Skip to content

Typcasting

2004 December 3
by Sven Busse

Juten Tach,

ein Thema, was schon hundertmal durchgekaut wurde, zumindest in anderen Programmiersprachen und welches jetzt auch in Flash, wo wir sowas lustiges wie Wenn-Du-willst-gerne-aber-muss-auch-nicht-Typisierung haben.

Also, warum das ganze? Folgendes Szenario: Wir haben eine Template Klasse, die soll später mal eine Seite anzeigen. So eine Seite besteht aus lauter lustigen Komponenten, also Bildern, Headlines, Links, Texten, Videos usw. Da all diese Komponenten bestimmte grundlegende Funktionen wie z.B. das Setzen des Inhalts (der Text, die Url des Bildes, die Url des Links usw.) benötigen, sehen wir eine allgemeine Klasse ‘Component’ vor. Die konkreten Komponenten erben dann von dem Ding. Eine Link Klasse würde dann wahrscheinlich neben vielen anderen Funktionen vielleicht noch sowas wie setHighlight() implementieren, nur mal als Beispiel.

So, unsere Template Klasse benötigt nun, warum auch immer, ein Array, in dem alle für diese Seite verwendeten Komponenten referenziert werden, nachdem sie erzeugt wurden. Intern hätte die Klasse also ihr Array:

private var _components:Array;

Und wir brauchen auch noch eine Funktion zum Hinzufügen von Komponenten und eine zum Herausnehmen:

public function setComponent(newComp:Component):Void{...}
public function getComponent(index:Number):Component {...}

So. Der Parameter und der Rückgabewert der einen bzw. der anderen Funktion muss natürlich vom Typ Component sein, denn es sollen ja alle möglichen Komponenten eintragbar sein.

So und jetzt geht’s schon los. Angenommen, ich habe jetzt eine Link-Komponente erzeugt und will sie nun eintragen:

var myLink:Link = new Link();
setComponent(myLink);

Jetzt fragt man sich vielleicht: “Moment, setComponent will doch vom Typ Component, warum geht das jetzt mit dem Link?” Weil Flash hier ein implizites Typcasting macht, sprich es ist immer erlaubt, vom Speziellen ins Allgemeine umzuwandeln und da muss man auch nix besonderes machen, das passiert dann einfach bei der Zuweisung bzw. in unserem Fall beim Funktionsaufruf.

Anders wäre es jetzt, wenn wir den umgedrehten Fall hätten. Angenommen also, unser Template wollte nur Links im Array speichern, dann würden wir sowas schreiben:

public function setLink(newLink:Link):Void{...}

Wenn wir nun eine Komponente vom Typ ‘Component’ erzeugen und zuweisen wollten, würde das schiefgehen:

var myComp:Component = new Component();
setLink(myComp); // Compiler würde hier 'Typdiskrepanz' melden

Macht ja auch Sinn, denn nicht jede Komponente ist mit einem Link kompatibel, hingegen ist jeder Link immer auch eine Komponente.

Es gibt aber Fälle, wo wir einfach wissen, dass unser Objekt vom Typ ‘Component’ eigentlich ein Link ist. Betrachten wir folgenden Verlauf:

var myLink:Link = new Link();
setComponent(myLink);
// So, jetzt also nur dieser Link im Array. weiter geht's.
var myOtherLink:Link = getComponent(0);
// ähh, geht nicht. getComponent liefert vom Typ Component,
// wir brauchen aber Link.

Ja, hier ist das Problem also noch mal illustriert. Jetzt ist das ja blöd, weil wir wissen ja, dass wir da einen Link reingetan haben, nur Flash weiss das nicht, Flash sieht nur, wir wollen einen ‘Link’, aber getComponent() liefert vom Typ ‘Component’. Wenn man sich also wirklich sicher ist, dass man eigentlich den richtigen Typ hat, kann man einen Typcast versuchen. Man schreibt dann also:

var myLink:Link = new Link();
setComponent(myLink);
// So, jetzt also nur dieser Link im Array. weiter geht's.
var myOtherLink:Link = Link(getComponent(0));

Jetzt haben wir Flash also explizit (deswegen hier auch explizites Typcasting, weil nicht automatisch) angewiesen, die Referenz auf das Objekt, welches getComponent liefert zuzulassen, weil wir wissen, dass sich dahinter ein Link verbirgt. Wenn es kein Link wäre, würde Flash hier nur ‘null’ liefern.

So, das war das. Ach übrigens, dieser ganze Spass gilt so nur für Objekte. Es gibt ja noch die primitiven Datentypen, wie einen String, womit ich nicht die String Klasse meine, sondern einen String selbst. Bei den primitiven Datentypen gibt es auch Typenumwandlung, allerdings findet hier tatsächlich eine Konvertierung statt, während wir da oben ja nie was konvertiert, sondern nur die Typdefinition angepasst haben.

No comments yet

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS

*