Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Polymorfismus = Mnohotvarost

Podobné prezentace


Prezentace na téma: "Polymorfismus = Mnohotvarost"— Transkript prezentace:

1 Polymorfismus = Mnohotvarost
Polymorfismus umožňuje hromadně zacházet s objekty téhož nadtypu, avšak jednotlivé se objekty chovají dle své povahy dané vlastním typem. Takové objekty mohou být referovány i z heterogenního pole či kolekce anebo jako argumenty metod. Polymorfismus je založen na: - schopnosti přetypování, tj. casting. - určení vlastního typu objektu v čase běhu pomocí RTTI ( Run Time Type Identification ). - pozdní vazbě, tj. na volání metod dle vlastního typu objektu, užitím RTTI , což spotřebuje určitý čas. ( Leč: static či private či final metody se volají časnou vazbou, neboť tyto se nedědí. Kompilátor tuto vazbu fixuje, čímž volání je rychlejší. ) - zpravidla zakrytých atributech. ( Atributy jsou vázány časnou vazbou. ) PJV03

2 garbage collected heap int compareTo( Object o) ;
Polymorfismus non-static context abstract Shape.class interface garbage collected heap Comparable.class double area( ) ; int compareTo( Object o) ; Shape[ ] s double perimeter( ) ; int compareTo( ) { } implementace komparability dle area( ) anebo perimeteru( ) Circle object Circle.class 3 double r s [ 0 ] double area( ) { PI*r*r } double perimeter( ){2*PI*r} Triangle object s [ 1 ] Triangle.class s [ 2 ] double a, b, c double area( ) { … } double perimeter( ){a+b+c} Rectangle object Rectangle.class double a, b double area( ) { a*b } double perimeter( ) {…} PJV03

3 Přetypování referenčních typů ( casting )
Přetypování je změna pohledu na objekt pomocí reference jiného typu. Typ objektu je neměnný - daný třídou dle níž byl zkonstruován. Přetypovat lze však jen v rámci dědičnosti, tj. pokud typ X je potomkem typu Y a Y je potomkem typu Z: Přípustnost kontroluje kompilátor. Předpokládejme: X x = new X(…); Přetypování přiřazením ( předek  potomek ): Y y = x ; ekvivalent k Y y = ( Y ) x ; Z z = y ; ekvivalent k Z z = ( Z ) y ; i k Z z = ( Z ) ( Y ) x ; Zpětné přetypování tj. casting ( potomek  předek ): y = ( Y ) z ; x = ( X ) y ; Chybným přetypováním dojde při běhu k výjimce ClassCastException. PJV03

4 Polymorfismus Polymorfismus je relace mezi referenčním typem a množinou objektů, které lze tímto typem referovat. Jsou-li dva typy referencí ( i nepřímo ) ve vztahu předek - potomek, pak lze potomka referovat jako předka. Jsou tři možnosti: Supertyp Subtyp Předek Potomek nadtřída  podtřída interfejs  třída nadinterfejs  podinterfejs Tím se však zúží přístup jen k těm členům ( atributům, metodám, vnitřním třídám a interfejsům ), které jsou definovány a přístupny v typu předka. PJV03

5 RTTI ( Run Time Type Identification )
Zjistit zda objekt patří právě k této třídě lze takto: ref.getClass( ).equals( SomeClass.class ) Zjistit zda dva objekty jsou stejného typu lze takto: ref1.getClass( ) == ref2.getClass( ) případně: ref1.getClass( ).equals( ref2.getClass( ) ) Primitivy mají také literály tříd, které jsou ekvivalenty obalových typů: boolean.class == Boolean.TYPE byte.class == Byte.TYPE int.class == Integer.TYPE .... double.class == Double.TYPE void.class == Void.TYPE PJV03

6 RTTI = Run Time Type Identification
Každý typ objekt má referenci k jedinému objektu typu java.lang.Class, který popisuje jeho třídu. Získat tuto referenci lze dvěma způsoby: SomeType ref = new SomeClass( ); Class c = ref.getClass( ); // using general method Class c = SomeType.class; // using class literal Pomocí c lze získat informace o typu a také o hodnotách atributů objektů daného typu. Takto lze získat informaci zda lze objekt referovat určitým typem, což pak umožňuje bezpečné přetypování: c.isInstance( ref ) metoda vrací boolean ref instanceof SomeType operátor vrací boolean PJV03

7 Přístup k atributům I k zastíněným atributům všech předků, lze přistupovat – pokud to dovolí jejich přístupové modifikátory. Obecná forma je: ( (Typ) ref ) . atribut Ekvivalentní formy ( kde inst resp. cls je instanční resp. třídní atribut ): Přístup k vlastnímu atributu: cls this.cls ( (Trida) this ).cls Trida.cls inst this.inst ( (Trida) this ).inst Přístup k zastíněnému atributu: super.cls ( (Predek) this ).cls Predek.cls super.inst ( (Predek) this ).inst Predek může být kterýkoli předek, super má význam přímého předka. Avšak klíčová slova this a super lze použít jen v nestatickém kontextu. Ze statického kontextu nelze přistupovat k instančním atributům. PJV03

8 Přístup k metodám Potomek může volat překryté metody předků (dovolí-li to jejich přístupový modifikátor ) avšak s určitým omezením pro instanční metody. Obecná forma je: ( (Typ) ref ) . metoda( … ) Ekvivalentní formy ( inst( ) resp. cls( ) je instanční resp. třídní metoda ): Volání vlastní metody: cls( ) this.cls( ) ((Trida) this).cls( ) Trida.cls( ) inst( ) this.inst( ) ((Trida) this).inst( ) Volání překryté metody předka: super.cls( ) ((Predek) this).cls( ) Predek.cls( ) super.inst( ) ((Predek) this).inst( ) <--- zavolá inst( ) Avšak klíčová slova this a super lze použít jen v nestatickém kontextu a nelze je kombinovat např. super.super či this.super . Důsledek významný pro polymorfismus: Byť je objekt referován typem některého předka zavolá se vždy instanční metoda definovaná ( tj. překrývající ) v jeho skutečném typu. PJV03

9 Příklad Co vytiskne následující sekvence ? A z = new B( );
System.out.print( z . i ); z . m( ); class A { int i = 1; // zastíněný atribut void m( ) { System.out.print( " A " + i ); } // překrytá metoda } class B extends A { int i = 2; // zastiňující atribut void m( ) { // překryvná metoda super . m( ); System.out.println( " B " + i ); PJV03

10 Řešení: 1 A 1 B 2 Object.class Halda A.class A object 1 B object
non-static context static context Object.class Halda class loader A z clone( ), equals( , hashCode( ), finalize( ), getClass( ), notify( ), notifyAll( ), toString( ), wait( ) A.class A object i 1 void m( ) { print “ A ” + i ; } B object B.class i 2 void m( ) { super . m( ) ; print “ B ” + i ; } Řešení: 1 A 1 B 2 PJV03


Stáhnout ppt "Polymorfismus = Mnohotvarost"

Podobné prezentace


Reklamy Google