140 likes | 320 Views
Eksempel på realisering af domænemodel. Del af design-klassediagram i et system til registrering af ansatte og projekter. Realisering af objektforbindelse. Designovervejelser Hvilken vej skal objekterne kunne tilgås Forbindelse til 1 objekt Simpel objektreference Forbindelse til * objekter
E N D
Eksempel på realisering af domænemodel • Del af design-klassediagram i et system til registrering af ansatte og projekter
Realisering af objektforbindelse • Designovervejelser • Hvilken vej skal objekterne kunne tilgås • Forbindelse til 1 objekt • Simpel objektreference • Forbindelse til * objekter • Reference til collection på 1-siden Se demo: demos\EmpProjV1
Nedarvning-generelt • Alle metoder bortset fra constructors arves. • private medlemmer af basisklassen nedarves, men kan ikke tilgås direkte. • Alle protected medlemmer af basisklassen er synlige nedad i arvehierakiet, men private for alle klasser udenfor. • Der kan tilføjes attributter og metoder i den nedarvede klasse • Ingen multipel arv • I C# arver alle klasser fra Object
OO-Principper-nedarvning • Nedarvning understøtter kodegenbrug • Nedarvning gør det muligt at udvide en eksisterende klasse. • Nedarvning er typespecialisering, dvs. vi modellerer et ”er-en” forhold mellem den nedarvede klasse og den der arves fra - fx: en Checkkonto er-en Konto. • Hvis vi står og mangler en klasse som er en specialisering af en klasse vi har, kan vi anvende nedarvning. • Fx Konto -> CheckKonto
OO-Principper-nedarvning • Den der arves fra kaldes basisklasse/superklasse. • Den der arver kaldes subklasse • Husk at der gælder et er-en forhold mellem sub- og basisklassen • En nedarvet klasse er typekompatibel med basisklassen: CheckKonto ck = new CheckKonto(); If (ck is Konto) returnerer true hvis CheckKonto arver fra Konto • Er-en forholdet er transitivt.
Nedarvning - Constructors • Basisdelen af en nedarvet klasse initialiseres ved kald til base(param-liste). • Kald til forfaders constructor er det første der sker i den nedarvede klasses constructor. • :base(param-liste) placeres umiddelbart efter constructorens metodehoved – notation taget fra C++ • Hvis man ikke definerer en constructor, genereres en default. Ved nedarvning kalder denne implicit en default constructor (parameterløs) på basisklassen.
Nedarvning - redefinering • En basisklasse-metode kan redefineres i den nedarvede klasse • Fx Haev-metoden på en Konto/CheckKonto • En basisklasse-metode der skal redefineres i den nedarvede klasse, skal erklæres virtual i basisklassen, og eksplicit overrides i den nedarvede klasse. • En override-metode tilsidesætter basisklassens metode. • Metoden i den nedarvede klasse skal have samme signatur og returtype som den virtuelle den redefinerer. • En redefineret metode kan kalde den metode den redefinerer i superklassens vha. base.metodenavn();
Nedarvning - polymorfi • Alle referencevariabler i C# kan referere objekter af nedarvede typer – (polymorf = mange former). • Ved virtuelle metoder træffes der beslutning på run-time om hvilken metode der skal kaldes. • Metoden der kaldes er den der er defineret på det objekt referencen i øjeblikket refererer. • Dette kaldes dynamisk binding.
Polymorfi/Dynamisk binding Statisk type Dynamisk type Som vi plejer at se det: Ansat programmør = new Ansat("KodeKarl","Programmør",22222); Statisk type = Dynamisk type Statisk metodekald Statisk type Dynamisk type • Med polymorft typesystem: • Ansat chef = new Chef(”Bosse",”Direktør",52525, 500); • Dynamisk type er samme som eller arving til statisk type • Compiler checker på statisk type om metode eksisterer, kald til metode vha. dynamisk binding • Dynamisk binding forudsætter at metoder er erklæret virtual
Nedarvning- override af ikke-virtual metoder • Hvad nu hvis vi glemmer at gøre vores metoder virtual, og en anden senere vil arve en af vores klasser og override en metode? • Svaret er new foran override-metoden
Substitutionsprincippet • Den dynamiske type skal altid kunne bruges i stedet for den statiske • Dvs., at objekter af en nedarvet type skal kunne anvendes i stedet for objekter af den oprindelige • De skal kunne substitueres • Dette sikres ved at vi ved redefinering af methoder kun afsvækker pre-betingelser og strammer post-betingelser.
Polymorfi- redefinering af metoder • Først implementerer vi metoden GivBonus(int belob) som virtual i klassen Ansat • Herefter redefiner vi den i klasserne Chef og Saelger • Endelig oprettes et array af Ansatte i main, hvor alle medarbejdere får 500,- i bonus Se demo: demos\EmpProjectV2
Nedarvning- designovervejelser • Lad os antage at vi skal bruge en klasse der kan indeholde en liste af ansatte, hvor det er muligt at tilføje sidst i listen, men ikke midt i – Skal vi arve fra Array, ArrayList eller? • Nej vi skal ikke arve, men bruge delegation • Arv bør ikke bruges blindt for at opnå kodegenbrug - arv er typespecialisering! • Arv skal kunne forsvares logisk som en ”A er-en B” • Kodegenbrug kan i stedet opnås ved at bygge oven på eksisterende klasser. Kaldes også for komposition, delegering, mm.