Chair of Software Engineering EinführungindieProgrammierung Prof.Dr.BertrandMeyer Lektion 11:Einführung in die Konzepte der Vererbung und Generizität Programmfürheute(undnächstesMal) ZweifundamentaleMechanismenfürmehrAusdruckskraft undVerlässlichkeit: Ø Generizität(genericity) Ø Vererbung(inheritance) Mitdendazugehörigen(genausowichtigen)Begriffen: Ø StatischeTypisierung(statictyping) Ø Polymorphie(polymorphism) Ø DynamischesBinden(dynamicbinding) 2 AusderzweitenVorlesung class PREVIEW inherit ZURICH_OBJECTS feature explore --DieStadterkunden. do Central•highlight Polyterrasse•highlight Polybahn•add_transport Zurich_map•animate end end 3 DenBegriffeinerKlasseerweitern Abstraktion Vererbung WAGEN_ MENGE Generizität Typ-Parametrisierung STADT_ LISTE Typ-Parametrisierung WAGEN_ LISTE PERSONEN_ LISTE VERKETTETE_WAGEN_ LISTE Spezialisierung 4 VererbungundGenerizitätverbinden Vererbung WAGEN_ MENGE PERSONEN_ MENGE Generizität STADT_ LISTE WAGEN_ LISTE VERKETTETE_ STADT_LISTE VERKETTETE_ WAGEN_LISTE PERSONEN_ LISTE 5 Generizität Uneingeschränkt: LIST[G] e.g.LIST[INTEGER],LIST[PERSON] Eingeschränkt: HASH_TABLE[G―>HASHABLE] VECTOR[G―>NUMERIC] 6 Generizität:Typ-Sicherheitgewährleisten Wiekönnenwirkonsistente„Container“-Datenstrukturendefinieren, z.B.eineListevonKontenodereineListevonPunkten? Aber:Was OhneGenerizitätvielleichtso: passiertbei einerfalschen Zuweisung? c:STADT;p:PERSON staedte:LIST... leute:LIST... --------------------------------------------------------- p leute.extend() staedte.extend() c c:=staedte.last c.stadt_operation 7 MöglicheAnsätze 1.DenCodeduplizieren,vonHandodermitHilfeeines Makroprozessors 2.BiszurLaufzeitwarten;fallsdieTypennichtpassen,eine Laufzeitausnahme(Smalltalk)werfen 3.Konvertieren(„cast“)allerWertezueinemuniversalenTyp, wiez.B.„Void-Zeiger“inC 4.ParametrisierenderKlasse,indemeinexpliziterNameGfür denTypderContainerelementeangegebenwird.Diesistder AnsatzinEiffel.AuchdieneustenVersionenvonJava,.NET undandereSprachenverwendendiesenAnsatz 8 EinegenerischeKlasse FormalergenerischerParameter classLIST[G]feature extend(x:G)... last:G... end UmdieKlassezuverwenden:Benutzensieeinegenerische Ableitung(genericderivation),z.B. TatsächlichergenerischerParameter staedte:LIST[STADT] 9 GebrauchgenerischerAbleitungen staedte:LIST[STADT] leute:LIST[PERSON] c:STADT p:PERSON ... staedte.extend(c) leute.extend(p) c:=staedte.last STATISCHETYPISIERUNG FolgendeswirdderCompiler zurückweisen: .extend(c) Ø leute Ø staedte .extend(p) c.stadt_operation 10 StatischeTypisierung TypsichererAufruf(type-safecall): WährendderAusführung:einFeatureaufrufx.f,sodass das an x gebundene Objekt ein Feature hat, das f entspricht. [Verallgemeinerung:mitArgumenten(z.B.x.f(a,b))] ÜberprüferfürstatischeTypen(typechecker): EinaufeinProgrammanwendbaresWerkzeug(z.B.ein Compiler) das — für alle Programme, die es akzeptiert — garantiert, dass jeder Aufruf in jeder Ausführung typsicherist. StatischtypisierteSprache: Eine Programmiersprache, für die es möglich ist, einen ÜberprüferfürstatischeTypenzuschreiben. 11 DerGebrauchvonGenerizität LIST[STADT] LIST[LIST[STADT]] … EinTypistnichtlängerdasGleichewieeineKlasse! (AbereinTypbasiertweiterhinaufeinerKlasse) 12 WasisteinTyp? (FürEinfachheitnehmenwiran,dassjedeKlasseentweder keinenodergenaueinengenerischenParameterhat) Typ Typ EinistvoneinerderfolgendenzweiArten: Ø Ø C,wobeiCderNameeinernicht-generischenKlasseist D[T],wobeiDderNameeinergenerischenKlasseundT Typ einist 13 EinegenerischeKlasse FormalergenerischerParameter classLIST[G]feature extend(x:G)... last:G... end UmdieKlassezuverwenden:Benutzensieeinegenerische Ableitung,z.B. TatsächlichergenerischerParameter staedte:LIST[STADT] 14 AusderzweitenVorlesung class PREVIEW inherit ZURICH_OBJECTS feature explore --DieStadterkunden. do Central•highlight Polyterrasse•highlight Polybahn•add_transport Zurich_map•animate end end 15 DenBegriffeinerKlasseerweitern Abstraktion Vererbung WAGEN_ MENGE Generizität Typ-Parametrisierung STADT_ LISTE Typ-Parametrisierung WAGEN_ LISTE PERSONEN_ LISTE VERKETTETE_WAGEN_ LISTE Spezialisierung 16 DiedualeNaturvonKlassen EineKlasseisteinModul. *OdereinTyp-Muster (template) EineKlasseisteinTyp*. (sieheGenerizität) EineKlassealsModul: Ø GruppiertMengevonverwandtenDiensten Ø ErzwingtdasGeheimnisprinzip(nichtjederDienstkann vonausserhalbgenutztwerden) Ø HatKlienten(Module,diesiebenutzen)undVersorger (Module,diesiebenutzt) EineKlassealsTyp: Ø BezeichnetmöglicheLaufzeitwerte(Objekteund Referenzen),dieInstanzendesTyps Ø KannfürDeklarationvonEntitätenbenutztwerden(die solcheWerterepräsentieren) 17 WiediebeidenAnsichtenzusammenpassen DieKlasse,alsModulgesehen: gruppierteineMengevonDiensten(dieFeaturesder Klasse), diegenaudenaufdieInstanzenderKlasse(alsTyp gesehen)anwendbarenOperationenentsprechen. (Beispiel:dieKlassePUBLIC_TRANSPORT,Featuresline, position,destination,speed,move) 18 GrundlagenderVererbung Prinzip: BeschreibungeinerneuenKlassealsErweiterungoder SpezialisierungeinerexistierendenKlasse. (Odermehreren,mitHilfevonMehrfachvererbung) FallsBvonAerbt: Ø AlsModule:AlleDienstevonAsindinBverfügbar. (MöglicherweisemitunterschiedlicherImplementation) Ø AlsTypen:Immer,wenneineInstanzvonAerwartet wird,istaucheineInstanzvonBerlaubt. (“isteineArtvon”-Beziehung(is-arelationship)) 19 Terminologie WennBvonAerbt(indemKlasseBKlasseAinihrerinheritKlauselauflistet): A Ø BisteinErbevonA Ø AisteinVorgängervonB FüreineKlasseA: Ø DieNachkommenvonAsindAselbstund (rekursiv)dieNachkommenvonAsErben. Ø EchteNachkommensindobigeohneA. B UmgekehrteNotation: Ø Vorfahre Ø EchterVorfahre GenauererBegriffderInstanz: Ø DirekteInstanzenvonA C D Ø InstanzenvonA:Diedirekten InstanzenvonNachkommenvonA. (AndereTerminologien:Unterklasse,Oberklasse) E 20 Beispielhierarchie(inTraffic) *aufgeschoben(deferred) +wirksam(effective) * MOBILE position* move* ++redefiniert(redefined) * TRANSPORT line departed destination move+ PUBLIC_TRANSPORT TOUR_TRAM position+ capacity passenger_count load TAXI take move+ name move++ 21 FeaturesimBeispiel Feature name:STRING --NamederRundfahrt. line:LINE --Linie,welcherderWagen --folgt. load(n:INTEGER) --LadenPassagiereauf. move(dt:INTEGER) --PositionnachdtMilli- --sekundenaktualisieren. AusderKlasse: * MOBILE TOUR_TRAM * TRANSPORT TAXI PUBLIC_TRANSPORT PUBLIC_TRANSPORT TOUR_TRAM TRANSPORT MOBILE 22 Featuresvererben deferredclass TRANSPORT inherit MOBILE feature […RestderKlasse…] end AlleFeaturesvonMOBILEsindauchin TRANSPORTverfügbar class PUBLIC_TRANSPORT inherit TRANSPORT feature […RestderKlasse…] end AlleFeaturesvonTRANSPORTsind auchinPUBLIC_TRANSPORTverfügbar class TOUR_TRAM inherit PUBLIC_TRANSPORT feature […RestderKlasse…] end AlleFeaturesvonPUBLIC_TRANSPORT sindauchinTOUR_TRAMverfügbar 23 VererbteFeatures m:MOBILE;t:TRANSPORT;p:PUBLIC_TRANSPORT; r:TOUR_TRAM * MOBILE m•move(…) t•load(…) * TRANSPORT p•line--EinAusdruck r•name--EinAusdruck TAXI r•move(…) PUBLIC_TRANSPORT r•load(…) r•line --EinAusdruck TOUR_TRAM r•name--EinAusdruck 24 Definitionen:ArtenvonFeatures Ein“FeatureeinerKlasse”ist: Ø EinvererbtesFeature,fallseseinFeatureeines Vorfahrensist,oder Ø EindirektesFeature,fallsesinderKlasseselbst definiertundnichtvererbtist.IndiesemFallsagtman, dassdieKlassedasFeatureeinführt 25 PolymorpheZuweisung t:TRANSPORT tram:PUBLIC_TRANSPORT cab:TAXI t:=tram EinechterNachkomme desursprünglichenTyps t " (TRANSPORT) Interessanter: ifbedingungthen t:=tram else t:=cab … end tram (PUBLIC_TRANSPORT) 26 Zuweisungen Zuweisung: ziel:=ausdruck Bisjetzt(ohnePolymorphie): ausdruckwarimmervomgleichenTypwieziel MitPolymorphie: DerTypvonausdruckisteinNachkommedesTyps vonziel 27 PolymorphiegiltauchfürArgumente reise_zeit(t:TRANSPORT):REAL_64 do…end EinspezifischerAufruf: reise_zeit(tram) DerTypdeseigentlichen Argumentsisteinechter NachkommedesTypsdes formalenArguments 28 Definitionen:Polymorphie engl.Attachment EineBindung(ZuweisungoderArgumentübergabe)ist polymorph,fallsihreZielvariableundderQuellausdruck verschiedeneTypenhaben. EineEntitätodereinAusdruckistpolymorph,fallssiezur Laufzeit—inFolgeeinerpolymorphenBindung—zu einemObjekteinesanderenTypsgebundenwerden. PolymorphieistdieExistenzdieserMöglichkeiten. 29 Definitionen:statischerunddynamischerTyp DerstatischeTypeinerEntitätistderTypihrerDeklaration imzugehörigenKlassentext. FallsderWerteinerEntitätwährendeinerAusführungan einObjektgebundenist,istderTypdiesesObjektsder dynamischeTypderEntitätzudieserZeit. 30 StatischerunddynamischerTyp t:TRANSPORT tram:PUBLIC_TRANSPORT StatischerTypvont: TRANSPORT t:=tram DynamischerTypnachdieserZuweisung: PUBLIC_TRANSPORT v " (TRANSPORT) cab (PUBLIC_TRANSPORT) 31 GrundlegendeTyp-Eigenschaft StatischerunddynamischerTyp DerdynamischeTypeinerEntitätistimmer konformzuihremstatischemTyp (vomTyp-Systemgarantiert) 32 StatischeTypisierung TypsichererAufruf(währendderAusführung): Ein Featureaufruf x.f , so dass das an x gebundene ObjekteinFeaturehat,dasfentspricht. [Verallgemeinerung:mitArgumenten(z.B.x.f(a,b))] ÜberprüferfürstatischeTypen: EinaufeinProgrammanwendbaresWerkzeug(z.B.ein Compiler) das - für alle Programme, die es akzeptiert - garantiert, dass jeder Aufruf in jeder Ausführung typsicherist. StatischtypisierteSprachen: Eine Programmiersprache, für die es möglich ist, einen ÜberprüferfürstatischeTypenzuschreiben. 33 VererbungundstatischeTypisierung ElementareTypisierungsregelbeiVererbung EinepolymorpheBindungistnurdanngültig, wennderTypderQuellemitdemTyp desZielskonformist konform:Grunddefinition Referenztypen(nichtgenerisch):UistkonformzuTfalls UeinNachkommevonTist EinexpandierterTypistnurzusichselbstkonform 34 Konformität:präzisereDefinition EinReferenztypUistzueinemReferenztypTkonform, falls: Ø SiedengleichengenerischenParameterhabenundU einNachkommevonTist,oder Ø SiebeidegenerischeAbleitungenmitdergleichen AnzahltatsächlicherParametersind,derVorfahrevon UeinNachkommederKlasseTistundjeder tatsächlicheParametervonU(rekursiv)zum jeweiligentatsächlichenParametervonTkonformist EinexpandierterTypistnurzusichselbstkonform. 35 StatischeTypisierung TypsichererAufruf(währendderAusführung): Ein Featureaufruf x.f , so dass das an x gebundene ObjekteinFeaturehat,dasfentspricht. [Verallgemeinerung:mitArgumenten(z.B.x.f(a,b))] ÜberprüferfürstatischeTypen: EinaufeinProgrammanwendbaresWerkzeug(z.B.ein Compiler) das - für alle Programme, die es akzeptiert - garantiert, dass jeder Aufruf in jeder Ausführung typsicherist. StatischtypisierteSprachen: Eine Programmiersprache, für die es möglich ist, einen ÜberprüferfürstatischeTypenzuschreiben. 36 DasVererbungs-undKonformitätssystem ANY Klassen(vom Progammierer definiert) NONE 37 NocheineBeispielhierarchie center* * OPEN_ FIGURE display* rotate* * FIGURE perimeter* * CLOSED_ FIGURE perimeter+ SEGMENT POLYLINE perimeter++ ... TRIANGLE *aufgeschoben +wirksam ++redefiniert perimeter+ + POLYGON perimeter++ + ELLIPSE ... side1 RECTANGLE side2 diagonal SQUARE CIRCLE perimeter++ 38 Redefinition1:Polygone classPOLYGONinherit CLOSED_FIGURE create make feature vertex:ARRAY[POINT] vertex[i] vertex_count:INTEGER perimeter:REAL --LängedesUmfangs. do from...until...loop vertex[i+1] . Result:=Result+vertex[i] distance(vertex[i+1]) ... end end invariant vertex_count>=3 vertex_count=vertex.count end 39 Redefinition2:Rechtecke classRECTANGLEinherit POLYGON redefine perimeter end create make feature diagonal,side1,side2:REAL perimeter:REAL --LängedesUmfangs. doResult:=2*(side1+side2)end invariant vertex_count=4 end diagonal side2 side1 40 Vererbung,TypisierungundPolymorphie Annahme: p:POLYGON;r:RECTANGLE;t:TRIANGLE x:REAL p ✂ Erlaubt: x:=p.perimeter x:=r.perimeter x:=r.diagonal p:=r NICHTerlaubt: (POLYGON) r (RECTANGLE) x:=p.diagonal--Auchdirektnachp:=r! r:=p 41 DynamischesBinden WasisthierdasResultat(fallsein_testwahrist)? ifein_testthen p:=r else p:=t end x:=p.perimeter Redefinition:EineKlassekanneingeerbtesFeatureändern. Beispiel:RECTANGLEredefiniertperimeter. Polymorphie:pkannzurLaufzeitmehrereFormenhaben. DynamischesBinden:DasResultatvonp.perimeterhängtvom derLaufzeitformvonpab. 42 Definition:DynamischesBinden(Dynamicbinding) DynamischesBinden(einesemantischeRegel): Ø JedeAusführungeinesFeatureaufrufsruftdasam bestenzumTypdesZielobjektsadaptierteFeature auf. 43 BindenundTypisierung (FüreinenAufrufxlf) StatischeTypisierung:DieGarantie,dassesmindestenseine Versionvonfgibt. DynamischesBinden:DieGarantie,dassjederAufrufdie geeignetsteVersionvonfaufruft. 44 OhnedynamischesBinden? display(f:FIGURE) do if“fisteinCIRCLE”then ... elseif“fisteinPOLYGON”then ... end end UndähnlichfüralleRoutinen! Lästig;mussimmerwiedergeändertwerden,wennes einenneuenFigurentypgibt. 45 MitVererbungundzugehörigenTechniken Mit: und: f:FIGURE c:CIRCLE . . createc make(...) createp make(...) p:POLYGON Initialisieren: if...then f:=c else f:=p end Danacheinfach: . . . f move(...) f rotate(...) f display(...) --undsoweiterfür --jedeOperationvonf! 46 Vererbung:Zusammenfassung1 Typenmechanismus:erlaubtes,Datenabstraktionenzu klassifizieren. Modul-Mechanismus:erlaubtes,neueKlassenalsErweiterung vonexistierendenKlassenzuerstellen. Polymorphie:FlexibilitätmitTyp-Sicherheit. DynamischesBinden:automatischeAdaptionderOperation aufdasZielfürmodularereSoftwarearchitekturen. 47 Redefinition classPUBLIC_TRANSPORTfeature departed:STATION --Abgangsstation. arriving:STATION --Ankunftsstation. towards_last:BOOLEAN --Fahrtrichtung. destination:STATION --Zielstation. move(dt:INTEGER) --PositionnachdtMillisekundenaktualisieren. do […] departed:=arriving ifarriving=destinationthen --Richtungwechseln. towards_last:=nottowards_last end arriving:=line.next_station(departed,towards_last) […] end […] end 48 Redefinition2:Tram-Rundfahrt classTOUR_TRAMinherit PUBLIC_TRANSPORT redefinemoveend feature move(dt:INTEGER) --PositionnachdtMillisekundenaktualisieren. do […] departed:=arriving ifarriving=line.lastthen --Richtungnichtwechseln. arriving:=line.first else arriving:=line.next_station (departed,towards_last) end […] end […] end 49 DynamischesBinden WasisthierdasResultat(fallsi_feel_like_fonduewahrist)? m:MOBILE,tram9:PUBLIC_TRANSPORT,fondue_tram:TOUR_TRAM ifi_feel_like_fonduethen m:=fondue_tram else m:=tram9 end . m move(5) Redefinition:EineKlassekanneingeerbtesFeatureändern.Beispiel: TOUR_TRAMredefiniertmove. Polymorphie:mkannzurLaufzeitmehrereFormenhaben. . DynamischesBinden:DasResultatvonm movehängtvonderLaufzeitform vonmab. 50 DynamischesBinden EsgibtmehrereVersionenvonmove. * MOBILE move* erbtvon * TRANSPORT move+ PUBLIC_TRANSPORT TOUR_TRAM *aufgeschoben TAXI move+ move++ 51 DenBegriffeinerKlasseerweitern Abstraktion Vererbung WAGEN_ MENGE Generizität Typ-Parametrisierung STADT_ LISTE Typ-Parametrisierung WAGEN_ LISTE PERSONEN_ LISTE VERKETTETE_WAGEN_ LISTE Spezialisierung 52 DenBegriffeinerKlasseerweitern Vererbung WAGEN_ MENGE PERSONEN_ MENGE Generizität STADT_ LISTE WAGEN_ LISTE VERKETTETE_ STADT_LISTE VERKETTETE_ WAGEN_LISTE PERSONEN_ LISTE 53 Konformität Vorherdefiniertfürnicht-generischabgeleiteteTypen: 54 Waswirgesehenhaben DiefundamentalenO-OMechanismen: Ø Vererbung Ø Polymorphie Ø DynamischesBinden Ø StatischeTypisierung Ø Generizität 55 UnserProgrammfürdenzweitenTeil Repetitionder(eingeschränkter)Generizität Vererbung:aufgeschobeneKlassen Vererbung:WaspassiertmitdenVerträgen? Vererbung:WiekönnenwirdentatsächlichenTypeines Objektesbestimmen? NichtindieserStunde,aberspäter:Mehrfachvererbung, Umbenennungenetc. 56 Generizität(Repetition) OhneEinschränkung LIST[G] e.g.LIST[INTEGER],LIST[PERSON] Eingeschränkt HASH_TABLE[G―>HASHABLE] VECTOR[G―>NUMERIC] 57 EinegenerischeKlasse(Repetition) FormalergenerischerParameter classLIST[G]feature extend(x:G)... last:G... end UmdieKlassezuverwenden:WirdeinegenerischeAbleitung benutzt,z.B. TatsächlichergenerischerParameter staedte:LIST[STADT] 58 GebrauchgenerischerAbleitungen(Repetition) staedte:LIST[STADT] leute:LIST[PERSON] c:STADT p:PERSON ... staedte.extend(c) leute.extend(p) c:=staedte.last STATISCHETYPISIERUNG FolgendeswirdderCompiler zurückweisen: .extend(c) Ø leute Ø staedte .extend(p) c.stadt_operation 59 Generizität:Zusammenfassung Ø MechanismuszurTyperweiterung Ø VereintTyp-SicherheitundFlexibilität Ø ErmöglichtparametrisierteKlassen Ø BesondersnützlichfürContainer-Datenstrukturen,wiez.B. Listen,Arrays,Bäume,… Ø “Typ”istnuneinwenigallgemeinerals„Klasse“ 60 Definition:Typ WirbenutzenTypen,umEntitätenzudeklarieren: x:SOME_TYPE MitdembisherigenMechanismusisteinTyp: Ø Entwedereinenicht-generischeKlasse,z.B. STATION Ø OdereinegenerischeAbleitung,z.B.derNameeinerKlasse, gefolgtvoneinerListevonTypen,dietatsächlichen generischenParameter,inKlammern,z.B. LIST[STATION] LIST[ARRAY[STATION]] 61 VererbungundGenerizitätverbinden Vererbung WAGEN_ MENGE PERSONEN_ MENGE Generizität STADT_ LISTE WAGEN_ LISTE VERKETTETE_ STADT_LISTE VERKETTETE_ WAGEN_LISTE PERSONEN_ LISTE 62 Generizität+Vererbung:eingeschränkteGenerizität classVECTOR[G]feature plusalias"+"(other:VECTOR[G]):VECTOR[G] --SummedesaktuellenVektorsundother. require lower=other.lower upper=other.upper local a,b,c:G do ...Siehenachher... end …andereFeatures... end 63 AddierenzweierVektoren u + v = w + b = c 2 i1 a 64 EingeschränkteGenerizität Rumpfvonplusalias"+": createResult.make(1,count) from i:=1 until i>count loop a:=Current[i] b:=other[i] c:=a+b --Benötigt“+”OperationaufG! Result [i]:=c i:=i+1 end 65 DieLösung DieKlasseVECTORdeklarierenals: classVECTOR[G–>NUMERIC]feature ...DerRestwiezuvor... end DieKlasseNUMERIC(vonderKernel-Bibliothek)enthältdie Featuresplusalias"+",minusalias"-"etc. 66 DieLösungverbessern MachensieausVECTORselbsteinNachkommevonNUMERIC: classVECTOR[G–>NUMERIC]inherit NUMERIC feature ...Restwievorher,einschliesslichinfix"+"... end DiesermöglichtdiefolgendenDefinitionen: v:VECTOR[INTEGER] vv:VECTOR[VECTOR[INTEGER]] vvv:VECTOR[VECTOR[VECTOR[INTEGER]]] 67 VererbungundGenerizitätverbinden Vererbung WAGEN_ MENGE PERSONEN_ MENGE Generizität STADT_ LISTE WAGEN_ LISTE VERKETTETE_ STADT_LISTE VERKETTETE_ WAGEN_LISTE PERSONEN_ LISTE 68 fleet:LIST[TRANSPORT] t:TRANSPORT extend(v:G) --EinneuesVorkommenvonvhinzufügen. … fleet.extend(t) fleet.extend(tram) (TAXI) (PUBLIC_ (TOUR_TRAM) (PUBLIC_ TRANSPORT) TRANSPORT) (TAXI) 69 Generizität+Vererbung2:PolymorpheDatenstrukturen bilder:LIST[FIGURE] p1,p2:POLYGON c1,c2:CIRCLE e:ELLIPSE classLIST[G]feature extend(v:G)do…end last:G … end bilder.extend(p1);bilder.extend(c1);bilder.extend(c2) bilder.extend(e);bilder.extend(p2) (POLYGON) (CIRCLE) (CIRCLE) (ELLIPSE) (POLYGON) 70 Beispielhierarchie center* * OPEN_ FIGURE display* rotate* * FIGURE perimeter* * CLOSED_ FIGURE perimeter+ SEGMENT POLYLINE *aufgeschoben +wirksam ++redefiniert + ELLIPSE ... ... perimeter++ perimeter+ + POLYGON TRIANGLE perimeter++ side1 RECTANGLE side2 diagonal SQUARE CIRCLE perimeter++ 71 MitpolymorphenDatenstrukturenarbeiten bilder:LIST[FIGURE] … acrossbilderascloop cl iteml display end (POLYGON) DynamischesBinden (CIRCLE) (CIRCLE) (ELLIPSE) (POLYGON) 72 Definition(Polymorphie,angepasst) EineBindung(ZuweisungoderArgumentübergabe)ist polymorph,fallsihreZielvariableundderQuellausdruck verschiedeneTypenhaben. EineEntitätodereinAusdruckistpolymorph,fallssie/er zurLaufzeit—inFolgeeinerpolymorphenBindung—zu einemObjekteinesanderenTypsgebundenwerden. EineContainer-Datenstrukturistpolymorph,fallssie ReferenzenzuObjektenverschiedenerTypenenthaltenkann. PolymorphieistdieExistenzdieserMöglichkeiten. 73 DieRollevonaufgeschobenenKlasse AusdrückenvonabstraktenKonzepten,unabhängigvonder Implementation. AusdrückenvongemeinsamenElementenvonmehreren Implementationen. Terminologie:wirksam=nichtaufgeschoben (d.h.vollständigimplementiert) 74 Beispielhierarchie center* * OPEN_ FIGURE display* rotate* * FIGURE perimeter* * CLOSED_ FIGURE perimeter+ SEGMENT POLYLINE *aufgeschoben +wirksam ++redefiniert + ELLIPSE ... ... perimeter++ perimeter+ + POLYGON TRIANGLE perimeter++ side1 RECTANGLE side2 diagonal SQUARE CIRCLE perimeter++ 75 AufgeschobeneKlasseninEiffelBase * CONTAINER * * BOX * FINITE * BOUNDED * COLLECTION * * INFINITE * UNBOUNDED * BAG * COUNTABLE TRAVERSABLE * SET * * TABLE LINEAR * BILINEAR INTEGER_ INTERVAL ACTIVE … * * RESIZABLE ARRAY INDEXABLE STRING HASH_TABLE * DISPENSER * STACK * … * * CURSOR_ STRUCTURE * HIERARCHICAL SEQUENCE * QUEUE *aufgeschoben 76 EinaufgeschobenesFeature InITERATION_CURSOR: forth require notafter deferred ensure index=oldindex+1 end 77 AufgeschobeneundwirksameFeaturesmischen IndergleichenKlasse wirksam! search(x:G) --GehezurerstenPositionnachder --aktuellen,woxauftritt,oderafter --fallsesnichtauftritt. do fromuntilafterorelseitem=xloop forth end end aufgeschoben “ProgrammemitLücken“ 78 “Rufensieunsnichtauf,wirrufensieauf!” EinemächtigeFormvonWiederverwendbarkeit: Ø Ø DaswiederverwendbareElementdefiniertein allgemeinesSchema. SpezifischeFällefüllendieLückenindiesemSchema KombiniertWiederverwendungmitAdaption 79 AnwendungvonaufgeschobenenKlassen AnalyseundEntwurf,vonobennachunten(top-down) Systematik GemeinsamesVerhaltenzusammenfassen 80 AufgeschobeneKlasseninEiffelBase * CONTAINER * * BOX * FINITE * BOUNDED * COLLECTION * * INFINITE * UNBOUNDED * BAG * COUNTABLE TRAVERSABLE * SET * * TABLE LINEAR * BILINEAR INTEGER_ INTERVAL ACTIVE … * * RESIZABLE ARRAY INDEXABLE STRING HASH_TABLE * DISPENSER * STACK * … * * CURSOR_ STRUCTURE * HIERARCHICAL SEQUENCE * QUEUE *aufgeschoben 81 EineAnwendung:Undo/Redo DiesesBeispielnutztwiederummächtigepolymorphe Datenstrukturen WirwerdennunnureineSkizzesehen,dieDetailswerdenin derLektionüberAgentenbesprochen. Referenzen: Ø Kapitel21inObject-OrientedSoftwareConstruction, PrenticeHall,1997 Ø ErichGammaetal.,DesignPatterns,Addison–Wesley, 1995:“Commandpattern” 82 DieProblemstellung DemBenutzereinesinteraktivenSystemsdieMöglichkeit geben,dieletzteAktionrückgängigzumachen. Bekanntals“Control-Z” SollmehrstufigesrückgängigMachen(“Control-Z”)und Wiederholen(“Control-Y”)ohneLimitierungunterstützen, ausserderBenutzergibteinemaximaleTiefean. 83 InunseremBeispiel:EinTexteditor Begriffder„aktuellenZeile“mitfolgendenBefehlen: Ø LöschenderaktuellenZeile Ø ErsetzenderaktuellenZeilemiteinerAnderen Ø EinfügeneinerZeilevorderaktuellenPosition Ø VertauschenderaktuellenZeilemitderNächsten(falls vorhanden) Ø „GlobalesSuchenundErsetzen“(fortanGSE):Jedes AuftreteneinergewissenZeichenkettedurcheine andereersetzen. Ø ... DerEinfachheithalbernutzenwireinezeilenorientierte Ansicht,aberdieDiskussionkannauchaufkompliziertere Ansichtenangewendetwerden. 84 EineeinfacheLösung SicherndesgesamtenZustandesvorjederOperation. ImBeispiel:DerText,derbearbeitetwird unddieaktuellePositionimText. WennderBenutzerein„Undo“verlangt,stelledenzuletzt gesichertenZustandwiederher. Aber:VerschwendungvonRessource,insbesondere Speicherplatz. Intuition:SicherenurdieÄnderungen(diff)zwischenzwei Zuständen. 85 Die„Geschichte“einerSitzungspeichern DieGeschichte-Liste: Einfügen Einfügen Löschen alt Einfügen Austauschen amneusten geschichte:LIST[BEFEHL] 86 Wasistein“Befehl”(Command)-Objekt? EinBefehl-ObjektbeinhaltetgenügendInformationenüber eineAusführungeinesBefehlsdurchdenBenutzer,um Ø denBefehlauszuführen Ø denBefehlrückgängigzumachen Beispiel:Ineinem“Löschen”-Objektbrauchenwir: • DiePositionderzulöschendenZeile • DerInhaltdieserZeile! 87 AllgemeinerBegriffeinesBefehls deferred class BEFEHL feature done:BOOLEAN --WurdedieserBefehlausgeführt? execute --EineAusführungdesBefehlsausführen. deferred ensure already:done end undo --EinefrühereAusführungdesBefehls --rückgängigmachen require already:done deferred end end 88 DieBefehl-Klassenhierarchie execute* undo* + LÖSCHEN execute+ undo+ line:STRING index:INTEGER *aufgeschoben * BEFEHL +wirksam + EINFÜGEN … execute+ undo+ index ... ... 89 ZugrundeliegendeKlasse(AusdemGeschäftsmodell) classEDIT_CONTROLLERfeature text:LIST[STRING] position:ITERATION_CURSOR[STRING] remove --LöscheZeileanaktuellerPosition. require notoff do position.remove end put_right(line:STRING) --FügelinenachderaktuellenPositionein. require notafter do position.put_right(line) end ...Auch:item,index,go_ith,put_left... end 90 EineBefehlsklasse(Skizze,ohneVerträge) classLÖSCHENinheritBEFEHLfeature controller:EDIT_CONTROLLER --ZugriffaufdasGeschäftsmodell. line:STRING --ZulöschendeZeile. index:INTEGER --PositionderzulöschendenZeile. execute --LöscheaktuelleZeileundspeicheresie. do line:=controller item;index:=controller index controller remove;done:=True end undo --FügevorhergelöschteZeilewiederein. do controller go_i_th(index) controller put_left(line) end end . . . . . 91 DieGeschichte-Liste EinepolymorpheDatenstruktur Einfügen Einfügen Löschen alt Einfügen Austauschen amneusten geschichte:LIST[BEFEHL] 92 Erinnerung:ListevonFiguren (POLYGON) (CIRCLE) (ELLIPSE) (CIRCLE) (POLYGON) bilder.extend(p1);bilder.extend(c1);bilder.extend(c2) bilder.extend(e);bilder.extend(p2) bilder:LIST[FIGURE] p1,p2:POLYGON c1,c2:CIRCLE e:ELLIPSE classLIST[G]feature extend(v:G)do…end last:G … end 93 DieGeschichte-Liste EinepolymorpheDatenstruktur Einfügen Einfügen Löschen Einfügen Austauschen alt amneusten geschichte:LIST[BEFEHL] cursor:ITERATION_CURSOR[BEFEHL] 94 EinenBenutzerbefehlausführen decode_user_request if“AnfrageistnormalerBefehl”then “ErzeugeeinBefehlsobjektc,derAnforderungentsprechend” geschichte extend(c) c execute Pseudocode,siehenächste Implementation elseif“AnfrageistUNDO”then . . . ifnotcursor beforethen--IgnoriereüberschüssigeAnfragen cursor item undo cursor back Einfügen Löschen Einfügen Austauschen end elseif“AnfrageistREDO”then . . . . ifnotcursor is_lastthen–IgnoriereüberschüssigeAnfragen cursor forth cursor item execute end end . . item . 95 DieBefehl-Klassenhierarchie execute* undo* + LÖSCHEN execute+ undo+ line:STRING index:INTEGER *aufgeschoben * BEFEHL +wirksam + EINFÜGEN … execute+ undo+ index ... ... 96 Beispielhierarchie center* * OPEN_ FIGURE display* rotate* * FIGURE perimeter* * CLOSED_ FIGURE perimeter+ SEGMENT POLYLINE *aufgeschoben +wirksam ++redefiniert + ELLIPSE ... ... perimeter++ perimeter+ + POLYGON TRIANGLE perimeter++ side1 RECTANGLE side2 diagonal SQUARE CIRCLE perimeter++ 97 EinenTyperzwingen:DasProblem bilder.store(“FN") ... --ZweiJahrespäter: bilder:=retrieved(“FN")–Siehenachher x:=bilder.last --[1] print(x.diagonal) --[2] Wasistdaranfalsch? Ø FallsxalsRECTANGLEdeklariertist,ist[1]ungültig. Ø FallsxalsFIGUREdeklariertist,ist[2]ungültig. 98 EinenTyperzwingen:DerObjekt-Test “Object-TestLocal’” ZuprüfenderAusdruck . ifattached{RECTANGLE}bilder retrieved("FN")asrthen print(r.diagonal) --Tuirgendwasmitr,welchesgarantiertnicht --VoidundvomdynamischenTypRECTANGLEist. else end print("Toobad.") SCOPEderObject-Local 99 FrühererMechanismus:Zuweisungsversuch f:FIGURE r:RECTANGLE ... bilder.retrieve("FN") f:=bilder.last r?=f ifr/=Voidthen . print(r diagonal) else print("Toobad.") end 100 Zuweisungsversuch(veraltetesKonstrukt) x?=y mit x:A Semantik: Ø FallsyaneinObjektgebundenist,dessenTypkonform zuAist:AusführungeinernormalenReferenzzuweisung. Ø Sonst:MachexVoid. 101 DieJavaund.NETLösung NurEinfachvererbungfürKlassen MehrfachvererbungvonSchnittstellen. EineSchnittstelleentsprichteinervollständigaufgeschobenen Klasse,ohneImplementationen(ohnedoKlauseln)und Attribute(undauchohneVerträge). 102 Mehrfachvererbung:Abstraktionenkombinieren <,<=, >,>=, COMPARABLE … NUMERIC +,–, *,/ … (kommutativer Ring) (Totale Ordnungsrelation) INTEGER REAL STRING COMPLEX 103 WieschreibenwirCOMPARABLE? deferredclassCOMPARABLEfeature lessalias"<"(x:COMPARABLE):BOOLEAN deferred end less_equalalias"<="(x:COMPARABLE):BOOLEAN do Result:=(Current<xor(Current=x)) end greateralias">"(x:COMPARABLE):BOOLEAN doResult:=(x<Current)end greater_equalalias">="(x:COMPARABLE):BOOLEAN doResult:=(x<=Current)end end 104 AufgeschobeneKlassenvs.Java-Schnittstellen Schnittstellensind„vollständigaufgeschoben“: nuraufgeschobeneFeatures AufgeschobeneKlassenkönnenwirksameFeaturesbeinhalten, dieaufaufgeschobenezugreifen,wieetwaimCOMPARABLEBeispiel. FlexiblerMechanismus,umAbstraktionenschrittweisezu implementieren. 105 AnwendungenvonaufgeschobenenKlassen Abstraktion Systematik AnalyseundEntwurfaufeinerhohenEbene … 106 Analysis-Beispiel:Fernsehstation classSCHEDULEfeature segments:LIST[SEGMENT] end Quelle:Object-OrientedSoftware Construction,2ndedition,PrenticeHall 107 Programme note Beschreibung: “24-StundenTVProgramm” deferredclassSCHEDULE feature segments:LIST[SEGMENT] --FolgevonSegmenten. deferred end air_time:DATE --24-Stunden-Periode --fürdiesesProgramm. deferred end set_air_time(t:DATE) --ZuweisungdesProgramms, --daszurZeittausgestrahlt --wird. require t.in_future deferred ensure air_time=t end print --Papier-Ausgabedrucken. deferred end end 108 Segment note Beschreibung:"Individuelle FragmenteeinesProgramms" deferredclassSEGMENTfeature schedule:SCHEDULEdeferredend --Programm,zuwelchemdas --Segmentgehört. index:INTEGERdeferredend --PositiondesSegment --inseinemProgramm. starting_time,ending_time: INTEGERdeferredend --BeginnundEndeder --geplantenAusstrahlungszeit. next:SEGMENTdeferredend --Segment,dasalsnächstes --ausgestrahltwird(fallsvorh.). sponsor:COMPANYdeferredend --HauptsponsordesSegments. rating:INTEGERdeferredend --Einstufung(geeignetfürKinder-- etc.). …Befehlewie change_next,set_sponsor,set_rating, omitted… Minimum_duration:INTEGER=30 --MinimaleLängedesSegmentes, --inSekunden. Maximum_interval:INTEGER=2 --MaximaleZeitzwischenzwei --aufeinanderfolgenden --Segmenten,inSekunden. 109 Segment(fortgesetzt) invariant . . in_list:(1<=index)and(index<=schedule segments count) . . in_schedule:schedule segments item(index)=Current next_in_list:(next/=Void)implies . . (schedule segments item(index+1)=next) . . no_next_iff_last:(next=Void)=(index=schedule segments count) non_negative_rating:rating>=0 positive_times:(starting_time>0)and(ending_time>0) sufficient_duration: ending_time–starting_time>=Minimum_duration decent_interval: (next starting_time)-ending_time<=Maximum_interval end . 110 Werbung note Beschreibung: „Werbeblock" deferredclassCOMMERCIALinherit SEGMENT renamesponsorasadvertizerend feature primary:PROGRAMdeferred --Programm,zuwelchemdie --Werbunggehört. primary_index:INTEGER deferred --Indexvon'primary´. set_primary(p:PROGRAM) --Werbungzuphinzufügen. require program_exists:p/=Void same_schedule: p.schedule=schedule before: p.starting_time<=starting_time deferred ensure index_updated: primary_index=p.index primary_updated:primary=p end 111 Werbung(fortgesetzt) invariant meaningful_primary_index:primary_index=primary index primary_before:primary starting_time<=starting_time acceptable_sponsor:advertizer compatible(primary sponsor) acceptable_rating:rating<=primary rating end . . . . . 112 Beispiel:ChemischesKraftwerk deferredclass VAT inherit TANK feature in_valve,out_valve:VALVE --FülledenTank. require in_valve.open out_valve.closed deferred ensure in_valve.closed out_valve.closed is_full end empty,is_full,is_empty,gauge,maximum,...[AndereFeatures]... invariant is_full=(gauge>=0.97*maximum)and(gauge<=1.03*maximum) end 113 VerträgeundVererbung Problem:WaspassiertbeiVererbungmit Ø Klasseninvarianten? Ø Vor-undNachbedingungenvonRoutinen? 114 Invarianten VererbungsregelfürInvarianten: Ø DieInvarianteeinerKlassebeinhaltetautomatischdie InvariantenallerVorfahren,„ver-und-et“. Die kumulierten Invarianten sind in der flachen Ansicht und derSchnittstellen-AnsichtinEiffelstudioersichtlich. 115 VerträgeundVererbung a1:A … a1 r(…) r A C α . ensure β KorrekterAufrufinC: ifa1.αthen a1.r(...) require D B r++ r --Hierista1.βerfüllt. end require γ ensure Klientvon erbtvon δ ++Redefinition 116 NeudeklarierungsregelfürZusicherungen WenneineRoutineneudeklariertwird,darfmannur: Ø DieVorbedingungbeibehaltenoderschwächen Ø DieNachbedingungbeibehaltenoderstärken 117 NeudeklarierungsregelfürZusicherungeninEiffel EinesimpleSprachregelgenügt! RedefinierteVersionendürfenkeineVertragsklauselhaben(Dann bleibendieZusicherungengleich)oder requireelsenew_pre ensurethennew_post DieresultierendenZusicherungensind: Ø original_preconditionornew_pre Ø original_postconditionandnew_post 118 Waswirgesehenhaben AufgeschobeneKlassenundihreRolleinSoftwareanalyseund –entwurf. VerträgeundVererbung Den„tatsächlichen“TypeneinesObjektesherausfinden 119