Objekt-Orientierte Programmiersprachen
Martin Gasbichler, Holger Gast 8. Dezember 2005
Heute: Interfaces
• Vererbung
• Jede Klasse hat genau eine direkte Superklasse
• Sie ¨ubernimmt die Implementierung der Superklasse
• Interfaces
• Klassen k¨onnen mehrere implementierte Interfaces deklarieren
• Sie erhalten dadurch keinen neuen Code
• Jedes Interface definiert einen Teilaspekt der Schnittstelle
⇒ Rollen im Responsibility Driven Design
• Zwei Implementierungen
• Interfaces als Multiple Inheritance
• Interface Dispatch Tables im GCJ
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 1
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 1
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 1
Das Beispiel
interface I { void f();
}
interface J extends I { void g();
}
class A implements I {
public void f() { System.out.println("A::f"); } }
class B extends A {
public void f() { System.out.println("B::f"); } }
class C extends A implements J {
public void g() { System.out.println("C::g"); } }
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 2
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 2
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 2
Das Beispiel
class Main {
public static void workI(I i) { i.f();
}
public static void workJ(J j) { j.f();
j.g();
}
public static void main(String argv[]) { workI(new A());
workI(new B());
workJ(new C());
} }
> java Main A::f
B::f A::f C::g
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 3
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 3
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 3
Interfaces in der JLS
§9: An interface declaration introduces a new reference type whose members are classes, interfaces, constants and abstract methods.
[. . . ] classes can implement it by providing implementations for its abstract methods.
§9.4: Everymethoddeclaration in the body of an interface is implicitly abstract [. . . ]. Every method declaration in the body of an interface is implicitly public.
§9.3: Every field declaration in the body of an interface is implicitly public, static, and final.
§9.3.1 Everyfieldin the body of an interface must have an initialization expression, which need not be a constant expression.
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 4
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 4
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 4
Abstrakte Methoden in Klassen
§8.4.3.1: An abstract method declaration introduces the method as a member, [. . . ] but does not provide an implementation. The declaration of an abstract method m must appear directly within an abstract class(call it A) [. . . ] Everysubclass of Athat is not abstract must provide an implementationfor m.
§8.1.1.1 An abstract class is a class that is incomplete, or to be considered incomplete. [. . . ] A compile-time error occurs if an attempt is made to create an instance of an abstract class using a class instance creation expression
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 5
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 5
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 5
Beispiel: Abstrakte Methoden
abstract class X {
public abstract void f();
}
class Y extends X {
public void f() { System.out.println("Y::f"); } }
class Z extends X {
public void f() { System.out.println("Z::f"); } }
• Einfache Vererbung (6.12.05)
• Xdeklariert Methode f
• YundZ ¨uberschreibenfmit eigenen Implementierungen
⇒ Dynamic dispatch wie bisher
• Unterschied: X hatte gar keine Implementierung f¨ur f angegeben, die
“¨uberschrieben” worden w¨are.
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 6
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 6
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 6
Tc Abstrakte Methoden
• ModulTc: Pr¨ufe, daß Methoden ohne R¨umpfe abstrakt sind let chk_meth m =
let should_have_body m = not(is_abstract_meth m) in
match m.meth_body with None ->
if should_have_body m
then type_error "non-abstract method without body"
• und daß Klassen mit abstrakten Methoden abstrakt sind let chk_cls cls =
if (exists (fun m -> is_abstract_meth m) (gather_meths_cls [] cls) &&
not (is_abstract_cls cls))
then type_error ("abstract method in non-abstract class "^
(string_of_qidentifier cls.cls_name));
gather_meths_clsist Hilfsmethode f¨ur Vererbung mit ¨Uberschreiben
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 7
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 7
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 7
Cg Abstrakte Methoden & Klassen
• Abstrakte Methoden: Durch ¨Uberschreiben bereits korrekt behandelt
• Abstrakte Klassen haben keine vollst¨andigen virtuellen Tabellen let def_cls_vtabs cls =
...
if is_abstract_cls cls
then [] (* cannot fill virtual tables for abstract classes *) else < Globale Variable f¨ur virtuelle Tabelle definieren >
• Abstrakte Klassen haben keine Instanzen let make_cls_allocator cls =
...
if is_abstract_cls cls then C.Decl_nil
else < Allocatorfunktion definieren >
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 8
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 8
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 8
Superinterfaces von Klassen (JLS §8.1.4)
The optional implements clause in a class declaration lists the names of interfaces that aredirect superinterfaces of the class [. . . ]
An interface type I is a superinterface of class type C if any of the following is true:
• I is a direct superinterface of C.
• I is asuperinterface of the direct superclass of C.
• C has some direct superinterface J for which I is a superinterface [. . . ]
A class is said toimplementall its superinterfaces.
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 9
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 9
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 9
R¨ uckf¨ uhrung: Interfaces → Abstrakte Methoden
• Abstrakte Methoden m¨ussen durch bei Vererbung implementiert werden
• Interfaces enthalten nur abstrakte Methoden
• Verbindung Interfaces – Klassen
§8.2: The members of a class type are all of the following:
• Members inherited from its direct superclass (§8.1.3)
• Members declared in the body of the class
• Membersinherited from any direct superinterfaces
⇒ Interaktion Interfaces / Abstrakte Methoden ist gekl¨art abstract class D
extends X implements I { }
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 10
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 10
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 10
Interfaces als Typen
• Interfaces definieren neue Referenztypen
• Zusammenhang mit Klassen-Typen
§5.1.4 The following conversions are called the widening reference conversions:
• From any class type S to any interface type K, provided that S implements K.
• From any interface type to type Object.
• [. . . weitere erlaubte Konversionen]
⇒ Polymorphie
• Eine KlasseC hat mehrere Typen
• Ihre direkte Superklasse C0(und deren Superklassen)
• Ihre direkten Superinterfaces
• Ein InterfaceI kann verschiedene Implementierungen besitzen
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 11
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 11
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 11
Zwischenstand: Interfaces
• Interfaces definieren Konstanten und abstrakte Methoden
• Klassen erben die (abstrakten) Methoden von ihren Superinterfaces
• Eine Klasse muss abstrakt sein, wenn sie abstrakte Methoden enth¨alt
(aber man darf auch Klassen ohne abstrakte Methoden als abstrakt deklarieren)
• Damit eine Klasse instanziiert werden kann, darf sie keine abstrakten Methoden enthalten. Insbesondere muss sie alle aus Interfaces geerbten Methoden ¨uberschreiben.
• Interfaces gelten als Supertypen ihrer implementierenden Klassen
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 12
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 12
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 12
Super- und Subinterfaces
§9.1.2 If an extends clause is provided [in an interface declaration], then the interface [. . . ] inherits the member types, methods, and constants of each of the other named interfaces. These other named interfaces are thedirect superinterfacesof the interface being declared.
[. . . ] Thesuperinterface relationship is the transitive closure of the direct superinterface relationship.
Any classthat implements the declared interface is also considered to implement all the interfaces that this interface extends.
• Superinterfaces parallel zu Superklassen
• Unterschied: Interfaces k¨onnen mehr als ein Superinterface besitzen
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 13
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 13
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 13
Vererbung bei Interfaces
§9.2: The members of an interface are:
• Those members declared in the interface.
• Those members inherited from direct superinterfaces.
• If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m [. . . ] corresponding to each public instance method m [. . . ] declared in Object.
• Vererbung wie bei Klassen: ¨Ubernehme Deklarationen
• Allerdings: Alle Methoden sind abstrakt, es gibt keine Implementierung
• Sonderfall Object: Es gibt kein InterfaceObject
• Interfaces sind ebenfalls Subtypen vonKlasse Object
• JLS sorgt daf¨ur, daß sie wirklich dessen Methoden enthalten
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 14
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 14
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 14
Konzept: Super- und Subtypen
• Superklassen und Superinterfaces haben vieles gemeinsam
⇒ Gemeinsame Abstraktion Supertypen / Subtypen
• Subtypen: F¨uhre Relation≤ auf Typen ein
• ≤ist transitiv und antisymmetrisch
• Beis≤theißtseinSubtypvontundteinSupertypvons
• Idee: Werte k¨onnen immer in Supertypen “konvertiert” werden
• Typregel: WenneTyp shat und s≤t, hateauch Typt.
• Erinnerung
v:s s≤t v:t
⇒ Subtyp-Polymorphie
• Werte haben eventuell mehrere Typen
• Eine Funktionf :t→t0nimmt alle Typens≤tals Eingaben
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 15
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 15
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 15
Konversion f¨ ur Interfaces
• Subinterfaces parallel zu Subklassen
• Abstraktion: Subtypen
⇒ Erwartung: Es gibt eine Konversion zwischen Interfaces
The following conversions are called the widening reference conversions:
• From any interface type J to any interface type K, provided that J is a subinterface of K.
• [. . . ]
⇒ Eine Referen mit Interfacetyp hat auch immer alle Superinterfaces des eigenen Typs als Typen
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 16
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 16
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 16
Implementierung von Interfaces
• Bedeutung und Typen sind klar, jetzt fehlt noch die Implementierung
• M¨oglichkeit 1: Mehrfachvererbung
• Grundsatz: Wennreine Referenz ist,
dann istr->_vtab die zugeh¨orige virtuelle Tabelle
• Erweitere Objekte um je eine virtuelle Tabelle je Interface
• M¨oglichkeit 2: Interface Dispatch Tables
• Interfaces definieren keinesfalls neue Instanzvariablen
⇒ Die volle Mehrfachvererbung ist “Kanone f¨ur Spatzen”
• Compiler weiss, wann Interface-Methode aufgerufen wird
⇒ Behandle Interface-Methodenaufrufe speziell
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 17
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 17
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 17
Probleme mit Virtueller Tabelle
• Sei Beine direkte Subklasse von A
• Wegen Polymorphie mussten wir Laufzeitdaten so w¨ahlen, daß jede B-Instanz wie eineA-Instanz benutzt werden kann.
• Position der geerbten Felder im Instanz-Struct
• Poisition der geerbten / ¨uberschriebenen Methoden in virtueller Tabelle
• int
•
•
Code vonA.e
Code vonB.f
Code vonB.g
int •
vtab i j
Instanz vonB VTab vonB e f g
⇒ Funktioniert nur f¨ur einen einzelnen Supertyp, weil er seine Eintr¨age am Anfang des Instanz-Structs und Virtueller Tabelle anlegen kann
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 18
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 18
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 18
Mehrfachvererbung
• Mehrfachvererbung
• Eine Klasse kann mehr als eine Superklasse besitzen
• Sie erbt Felder und Methoden von allen Superklassen
• Ist in Java nicht vorgesehen, aber in C++ (:n¨achste Woche)
• Heute schon: Implementierungsmodell von C++ einf¨uhren
⇒ L¨osung f¨ur Java-Interfaces: Betrachte sie als Superklassen
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 19
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 19
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 19
Beispiel Mehrfachvererbung
class A { int i;
void f() { System.out.println(i); } }
class B { int j;
void g() { System.out.println(j); } abstract void a();
}
class C extends A,B { int k;
void h() { System.out.println(k); } void a() { System.out.println(k); } }
• Fikitve Erweiterung von Java: Mehrere Klassen bei extends
• Methoden greifen auf Instanzvariablen zu
• C hatte alle Methoden und Instanzvariablen vonA undB
• C ¨uberschreibt die abstrakte Methodeaaus B
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 20
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 20
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 20
Grundidee Implementierung
• int
• int int
•
•
•
•
•
•
Code vonA.f
Code vonB.g
Code vonC.a
Code vonC.h vtabC
i vtabB j k
f g a h
g a
• Prinzip
• Setze Instanz-Struct aus Instanzen aller Superklassen zusammen
• Die erste Superklasse wird wie bei Einfachvererbung behandelt
• Instanz-Structs der Superklassen m¨ussen auch virtuelle Tabelle enthalten
• Die Methoden der Superklassen erwarten vollst¨andige Instanzen
• Eine Widening Conversion ergibt Zeiger auf Teilbereich der Instanz
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 21
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 21
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 21
Methodenaufrufe
• Sei rReferenz aufC-Instanz-Struct
• Methode mit Code ausA: r.f():r->_vtabC->f(r)
• Methode mit Code ausB: r.g():r->_vtabC->g(r+8)
• this=r Zeiger verweist aufC-Objekt
⇒ M¨ussen Zeiger auf ein B-Objekt alsthis¨ubergeben
⇒ Offset berechnen (Annahme: sizeof(int)=4)
• Methode mit Code ausC: r.a():r->_vtabC->g(r)
• Methode mit Code ausC: r.h() :r->_vtabC->a(r)
• Methodeawurde inB deklariert
• Weil der Code aber inCdefiniert ist, erwartet er eine C-Instanz
⇒ Kein Offset f¨ur thisbeim Aufruf
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 22
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 22
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 22
Problem der Grundidee
• Aus r.a()-Beispiel: Die ¨uberschreibende Methode bestimmt, welche Instanz-Struct alsthiserwartet wird
• Die ¨uberschreibende Methode ist aber erst zur Laufzeit bekannt!
• Beispiel: Die Methodea
• B b = rergibt Referenzbauf Instanz-Struct bei_vtabB
• Aufrufb.a()f¨uhrt aber Code f¨ur Instanz vonCaus
• Dieser Code erwartet Variablek im 5-ten Feld des Instanz-Structs
• Der Instanz-Struct beibhat aber nur 2 Felder (_vtabBundj)
und Feldk, das aber inBnicht beschrieben ist
⇒ Der richtige this-Zeiger muss zur Laufzeit ermittelt werden
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 23
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 23
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 23
L¨ osung: Offsets f¨ ur Methodenaufruf
• Ziel: Der richtige this-Zeiger muss zur Laufzeit ermittelt werden
• L¨osung: Speichere in virtueller Tabelle Paare(∆, m)
• mist Funktionszeiger wie bisher
• ∆ist Offset zum thisObjekt, das der Code von merwartet
• Der Compiler weiss, woher der Code f¨urmstammt und kann∆berechnen
• Methodenaufruf f¨urr.m(a1, . . . , am) allgemein
r->_vtab->m(r+r->_vtab->∆, a1, . . . , an)
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 24
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 24
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 24
Beispielmethode a
• F¨ur aist ∆a=−8 =2·sizeof(int)
• (Hinweis: Offsets bei Methoden sind immer negativ)
• Haben ReferenzB b = rwie vorher
• Aufruf: r->_vtab->a(r−8)
• F¨uhrt Code ausC mit C-Instanz aus
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 25
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 25
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 25
Mehrfachvererbung f¨ ur Interfaces
• Betrachte Klasseclass Y extends X implements I1, . . . , In
• Behandle Vererbung vonXwie bisher auch
• Behandle Interfaces I1, . . . , Indurch Mehrfachvererbung
• Lege virtuelle Tabelle f¨ur jedes Interface an
• Speichere in Y-Instanz am Ende Zeiger auf diese virtuellen Tabellen
• Konversion zu InterfaceIj ergibt Referenz auf Teil derY-Instanz
Variablen von X
•
Variablen von Y
•
•
· · · vtabY
vtabI1 vtabI2
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 26
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 26
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 26
Mehrfachvererbung f¨ ur Interfaces
• Beobachtung
• Alle Methoden derI1. . . Insind abstrakt
⇒ Der Code f¨ur die Methoden stammt aus Xoder Y
⇒ Er erlaubt alsthis-Objekt in jedem Fall eine Referenz auf dieY-Instanz
⇒ Gleicher Offset∆bei allen Methoden einer virtuellen Tabelle
⇒ Speichere Offset∆am Anfang der Tabelle statt bei Methoden
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 27
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 27
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 27
Laufzeitdaten f¨ ur Interfaces
---Rt tables --- type vtab = {
mutable vtab_decl_nm : string;
mutable vtab_def_nm : string option;
mutable vtab_has_off : bool;
mutable vtab_entries : vtab_entry list;
}
type inst_entry = Inst_field of field
| Inst_interface of inst_interface and inst_interface = {
ii_nm : string;
ii_interface : interface;
ii_inst : inst;
}
and inst = {
inst_decl_nm : string;
mutable inst_vtab : vtab;
inst_entries : inst_entry list;
}
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 28
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 28
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 28
Cg f¨ ur Interface-Methoden
| Exp_call(e’,id,args) ->
let exp’ = cg_exp e’ in
let this = Temps.end_and_alloc (exp_ty e’) in let args’ = map cg_exp args in
let argtmps = map (fun a -> Temps.alloc (exp_ty a)) args in
let argass = map2 (fun t a -> C.Exp_assign(t, a)) argtmps args’ in let meth = exp_acc_meth exp in
• Erinnerung
• this-Objekt
• Tempor¨are Variable f¨ur Argumente
• Argument auswerten in argass
• methist die vom Typchecker ausgew¨ahlte Methode
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 29
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 29
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 29
Cg f¨ ur Interface-Methoden
match exp_ty e’ with
| Ty_ref(Rty_interface i) ->
let inst = interface_inst i in C.Exp_seq([
C.Exp_assign(this, exp’) ] @ argass @ C.Exp_call(
C.Exp_deref_acc( C.Exp_deref_acc(
C.Exp_cast(C.Ty_ptr(C.Ty_struct_ref(inst.inst_decl_nm)), this), "_vtab"),
meth_nm meth), (C.Exp_opbin(
this,"-",
C.Exp_deref_acc(C.Exp_deref_acc(
C.Exp_cast(C.Ty_ptr(C.Ty_struct_ref(inst.inst_decl_nm)), this),"_vtab"),"_off")))
:: argtmps) ])
• Greife wie bisher auf virtuelle Tabelle zu
• Setze nicht thisvorargtmpssondern subtrahiere ∆
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 30
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 30
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 30
Beispielaufruf
interface I { void f();
}
class A implements I { int i;
void f() { System.out.println_int(i); } }
class Main {
public static void main(String argv[]) { i = new A();
i.f();
} }
((_tmp_RI_0)=(i$2),
((((struct I$obj*)(_tmp_RI_0))->_vtab)->f$1)(
(_tmp_RI_0)-((((struct I$obj*)(_tmp_RI_0))->_vtab)->_off)));
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 31
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 31
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 31
Zusammenfassung: Mehrfachvererbung
• Interfaces durch Mehrfachvererbung implementieren
• Bei Mehrfachvererbung kann eine Klasse mehrere Superklasse haben
• Der Instanz-Struct der Subklasse enth¨alt dann einen vollst¨andigen Instanz-Struct f¨ur jede Superklasse
• F¨ur die erste Superklasse wie bei Einfachvererbung am Anfang
• F¨ur alle weiteren die Felder und virtuelle Tabelle der Superklasse
• Eine Konversion zu einer Superklasse ¨andert die Referenz
• Methodenaufrufe sind problematisch:
• Subklasse ¨uberschreibt eine Methode
⇒ Code erwartet Instanz der Subklasse
• Nach Konversion steht aber nur Instanz der Superklasse zur Verf¨ugung
• L¨osung: Offsets in der Methodentabelle
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 32
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 32
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 32
Interface Dispatch Tables
• Interfaces durch Mehrfachvererbung sind ineffizient
• In jedem Objekt liegt ein Zeiger pro implementiertem Interface
• Diese Zeiger sind gleich in allen Instanzen
⇒ Speicherplatz wird unn¨utz verschwendet
• Gesucht: Eine L¨osung
• die keinen zus¨atzlichen Speicherplatz in Instanzen ben¨otigt
• trotzdem den Methodenaufruf inO(1)zul¨aßt
• Interface Dispatch Tables (IDT)
• werden vomgcjeingesetzt (gcc-Frontend f¨ur Java)
• sind vergleichsweise neu (“publiziert” auf Mailingliste 2001)
• sind ziemlich cool
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 33
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 33
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 33
Grundidee: Zuordnungsmatrix
• Betrachte Aufruf i.m()(mitI i)
• Sei C dynamischer Typ von i(durch VTab in ierkennbar)
• Gesucht: FunktionIMPL(I, C, m) =p
• Ergibt Zeigerpauf auszuf¨uhrenden Code
• Sollte inO(1)berechnet werden k¨onnen
• Vereinfachung:
• F¨ur jede KlasseC, dieI implementiert, lege virtuelle Tabelle IC wie bisher an.
• Noch gesucht: VTAB(I, C) =IC
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 34
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 34
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 34
Erste L¨ osung: Wir ham’s doch!
• ImplementiereVTAB(I, C) =IC durch Matrix
vgl. Driesen, Karel: Selector Table Indexing & Sprase Arrays, OOPSLA’93
• Nummeriere Interfaces und Klassen durch
• Seiα(I) der Index von InterfaceI
• Seiβ(C)der Index der KlasseC
• Speichereβ(C)in virtueller Tabelle vonC ab
• Lege Matrix anVTAB[α(I)][β(C)] =IC
• Methodenaufruf
• Instanz h¨alt_vtabZeiger mit Tabelle des dynamischen Typs
• Erhaltenβ(C)des dynamischen Typs
• α(I)ist schon dem Compiler bekannt nach statischem Typ 3 Compiler kannVTABvorausberechnen
7 VTABbraucht viel Speicherplatz und die meisten Eintr¨age sind leer
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 35
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 35
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 35
Idee: Vermeide leere Eintr¨ age
• Beobachtung: Ein Interface wird nur von einem Bruchteil aller Klassen implementiert
⇒ Die Zeilen der MatrixVTAB[α(I)][β(C)]sind relativ leer
⇒ Lege f¨ur ein Interface nur den wirklich ben¨otigten Teil seiner Zeile an
• Problem: H¨ochster Index β(C)ist immer noch die Anzahl der Klassen
⇒ Die Einsicht
• Wir m¨ussen einigeβ mehrfach vergeben!
• Solange bei β(C) = β(C0) die Klassen C und C0 nicht das gleiche Interface implementieren geht alles gut
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 36
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 36
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 36
IDT Datenstruktur (I)
• Lege f¨ur jede Klasse C eine virtuelle TabellevtabC an
• Normale virtuelle Tabelle f¨ur (Einfach-)Vererbung
• F¨ur jedes von C implementierte Interface eine Teiltabelle IC mit den Methodenzeigern f¨ur I-Methoden
• Seiγ(C, I)der Offset, an demIC invtabC beginnt
3 Alle Methodenzeiger sind an einem zentralen Punkt gesammelt 3 Es wurde kein Platz verschwendet, alle Eintr¨age sind n¨otig
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 37
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 37
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 37
IDT Datenstruktur (II)
• Zur Laufzeit bekannt
• InterfaceI (vom Compiler berechnet)
• MethodenminI
• Der dynamische TypC des Zielobjektes
• Gesucht nur noch: Verbindung von I mitIC
• Lege f¨ur jedes InterfaceI eine TabelleIDTI mit diesem Verweis an
• Trick: F¨ur Verweis reicht Offsetγ(C, I), denn vtabC haben wir schon
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 38
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 38
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 38
IDT Datenstruktur (III)
• Annahme: Wir haben schonIDTI angelegt f¨ur jedes InterfaceI angelegt
• SeiC eine neue Klasse mit implementierten Interfaces I1. . . In
⇒ Wir m¨ussenIDTIj[β(C)] =γ(C, I) setzen . . . f¨ur ein geeignetesβ(C)
• Trick: β(C)wird nur in den Tabellen vonI1. . . Inverwendet
⇒ W¨ahle β(C) so daß der Eintrag IDTIj[β(C)] noch unbelegt ist f¨ur alle j= 1, . . . , n
• Falls n¨otig, erweitere die TabellenIDTIj um einen neuen Eintrag
• Legeβ(C) inVTABC ab
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 39
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 39
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 39
IDT im Bild
β(C) I1,C
... In,C
· · · γ(C, I1)
· · ·
· · · γ(C, In)
· · · IDTI1
IDTIn
VTABC
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 40
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 40
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 40
IDT Methodenaufruf
• Zur Laufzeit bekannt
• InterfaceI (vom Compiler berechnet)
• MethodenminI
• Der dynamische Typ C des Zielobjektes
• Bestimmung des Methodenzeigers
• Hole β(C)aus der virtuellen Tabelle
• Bestimme dannγ(C, I) =IDTI(β(C))
• Hole Funktionszeiger ausVTABC(γ(C, I))
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 41
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 41
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 41
Zusammenfassung IDT
3 Zugriff MethodenzeigerO(1) 3 Kein Platz in Instanz f¨ur Interfaces
3 Kein / Wenig Speicherplatz in Tabellen verschwendet 3 Dasthis-Objekt ist das Zielobjekt
• Keine Offsetberechnungen beim Methodenaufruf
• Keine Berechnungen bei Konversionen notwenig
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 42
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 42
M. Gasbichler, H. Gast Interfaces (OOPS, 8.12.2005) Seite 42