TDDC76 Programmering och datastrukturer Arv, polymorfi och objektorienterad programmering Oskar Holmström Institutionen för datavetenskap
Agenda 1 Pekare 2 Arv 3 Statisk bindning 4 Polymorfi 5 Destruktorer 6 Synlighet 7 UML 8 Arv - ett stort exempel
Dagens föreläsning Vad ska vi göra idag? Klasser var bra för att skapa en representation av objekt. Hur skapar vi en representation av en grupp objekt som hänger ihop? 3
Dagens föreläsning Vad ska vi göra idag? Klasser var bra för att skapa en representation av objekt. Hur skapar vi en representation av en grupp objekt som hänger ihop? Med arv och polymorfi två av de starkaste verktygen för att göra vårt liv lättare. 4
Pekare Pekar oss mot rätt minnesadress 5
Pekare Pekar oss mot rätt minnesadress Vi har pratat om Variabler innehållet i lådan Referenser tillgång till lådan 6
Pekare Pekar oss mot rätt minnesadress Vi har pratat om Variabler innehållet i lådan Referenser tillgång till lådan Nu, pekare en variabel som lagrar en adress 7
Pekare Pekar oss mot rätt minnesadress En pekare är en variabel som innehåller en adress Adressen kan leda till en variabel Tänk adressen till ett hus Får du adressen kan du hitta till huset Ändrar du något på huset kommer ändringen vara där när jag också besöker adressen 8
Pekare Vad händer i minnet? Datorn har ett internminne (RAM random access memory) Ordnad sekvens bitar Kan normalt adressera en byte (8 bitar) i tage En processor arbetar normalt med ord (idag ofta 64 bitar) i taget En pekar-adress gör att vi kan komma åt platser i internminnet (Ex. på adress 0x1001054a0) 9
Pekare Vad händer i minnet? En variabel har alltid namn, datatyp och värde Kompilatorn: Översätter namnet till en adress Bestämmer mängden minne (i byte) som behövs utifrån datatypen Tolkar innehållet, värdet, enligt vald datatyp 10
Pekare Måste en pekare peka någonstans? Variabler får alltid ett värde har pekarvariabler det också? Det måste alltid finnas något i variabeln, fast pekaren kan peka till ingenting När pekaren inte pekar någonstans har den ett null-värde Kallas en null-pekare Null-pekare räknas som false i ett villkor 11
Pekare Hur deklarerar vi en pekar-variabel? Pekarvariabler deklareras med en asterisk (*) som datatyp Förutom (*) måste vi ange vilken datatyp som finns på adressen! int * p; p: *? 12
Pekare Hur deklarerar vi en pekar-variabel? Pekarvariabler deklareras med en asterisk (*) som datatyp Förutom (*) måste vi ange vilken datatyp som finns på adressen! int * pnullptr; //null_ptr p: * 13
Pekare Hur deklarerar vi en pekar-variabel? Pekarvariabler deklareras med en asterisk (*) som datatyp Förutom (*) måste vi ange vilken datatyp som finns på adressen! int x3421; int * p&x; p: * int x: 3421 14
Pekare Pekar-operatorer Avreferens (innehållet av pekare, gå till ): *p int x3421; int * p&x; *p = 10; int x: 3421 p: * 15
Pekare Pekar-operatorer Avreferens (innehållet av pekare, gå till ): *p int x3421; int * p&x; *p = 10; int x: 10 p: * 16
Pekare Pekar-operatorer Adress av: & Ger adressen i minnet till en variabel int x3421; int * p&x; int x: 3421 p: * 17
Pekare Pekar-operatorer Säg att pekaren pekar på en klass, då vill vi komma åt dess medlemmar Avreferens och välj medlem: (*p).m eller p->m string str Hej ; string * p&str; cout << p->length() << endl; cout << (*p).length() << endl; p: * string str: Hej 18
Pekare Pekar-operatorer Dynamiskt allokera (låna) minne: p = new t eller a = new t[i] Avallokering: delete p eller delete a[] string * p = new string; *p = Hej ; delete p; p: * str: string 19
Pekare Pekar-operatorer Dynamiskt allokera (låna) minne: p = new t eller a = new t[i] Avallokering: delete p eller delete a[] string * p = new string; *p = Hej ; delete p; p: * string str: Hej 20
Pekare Pekar-operatorer Dynamiskt allokera (låna) minne: p = new t eller a = new t[i] Avallokering: delete p eller delete a[] string * p = new string; *p = Hej ; delete p; 21
Pekare this en pekare till instansen vi är i Vi har skapat en klass och en instans (objekt) av den klassen I en medlemsfunktion vill vi returnera en kopia av vår instans A_class A_class::copy_myself() return *this; this är en pekare till instansen som vi ropat copy_myself på OBS! Lätt att överanvända, så använd sparsamt. 22
Pekare Mer nästa gång Detta var en kort introduktion till vad pekare är, hur vi skapar dem och vilka operationer vi kan utföra på dem Nästa föreläsning kommer vi göra ett djupdyk i pekare och speciellt hantering av minne 23
Arv Varför är arv användbart? Möt tre studenter: Gymnasiestudenten Gabriella Högskolestudenten Harry Impulsive Ivar Alla tre har vissa gemensamma egenskaper (både attribut och funktioner), men även olikheter! 24
Arv Varför är arv användbart? Möt tre studenter: Gymnasiestudenten Gabriella Högskolestudenten Harry Impulsive Ivar Alla tre har vissa gemensamma egenskaper (både attribut och funktioner), men även olikheter! Har ett skåp Gillar att lösa problem med penna och papper 25
Arv Varför är arv användbart? Möt tre studenter: Gymnasiestudenten Gabriella Högskolestudenten Harry Impulsive Ivar Alla tre har vissa gemensamma egenskaper (både attribut och funktioner), men även olikheter! Har ett antal avklarade HP Gillar att lösa problem med en väl skriven programmeringsalgoritm 26
Arv Varför är arv användbart? Möt tre studenter: Gymnasiestudenten Gabriella Högskolestudenten Harry Impulsive Ivar Alla tre har vissa gemensamma egenskaper (både attribut och funktioner), men även olikheter! Gillar huvudbonader och att gå ut på rast Vägrar att lösa problem 27
Arv Varför är arv användbart? Hur representerar vi de tre studenterna med klasser? Alternativ 1: En monsterklass! class student public: string name; int type; Int age; 28
Arv Varför är arv användbart? Hur representerar vi de tre studenterna med klasser? Alternativ 1: En monsterklass! class student public: stringgenerell name; del int type; Int age; Specifik del Specifik del Specifik del 29
Arv Varför är arv användbart? Hur representerar vi de tre studenterna med klasser? Alternativ 1: En monsterklass! class student public: string name; int type; Int age; Generell del Specifik del void Student::study() if (type == 1) cout << Lös med algoritm! ; Specifik del Specifik del else if (type == 2) cout << Lös med pennna och papper ; else if( type == 3) cout << Jag vägrar!! ; 30
Arv Varför är arv användbart? Hur representerar vi de tre studenterna med klasser? Alternativ 1: En monsterklass! class student public: string name; int type; Int age; Generell del Specifik del Specifik del Specifik del Ger fullständig uppräkning Svårt att underhålla och utöka Skulle inte vårt liv bli lättare efter FÖ1? Detta är för dåligt 31
Arv Varför är arv användbart? Hur representerar vi de tre studenterna med klasser? Alternativ 2: Separata klasser class High_Shool_Student public: string name; int age; class College_Student public: string name; int age; class Young_Student public: string name; int age; 32
Arv Varför är arv användbart? Hur representerar vi de tre studenterna med klasser? Alternativ 2: Separata klasser class High_Shool_Student class College_Student class Young_Student public: Generell del public: Generell del public: Generell del string name; string name; string name; int age; int age; int age; Specifik del Specifik del Specifik del 33
Arv Varför är arv användbart? Hur representerar vi de tre studenterna med klasser? Alternativ 2: Separata klasser class High_Shool_Student public: Generell del public: Generell del public: Generell del string name; string name; string name; int age; int age; int age; class College_Student class Young_Student Specifik del Specifik del Specifik del Nu ansvarar klassen själv för funktionalitet Blir massa kodduplicering! Lättare att utöka Svårt att underhålla 34
Arv Varför är arv användbart? Alternativ 3: Arv från gemensam basklass! class student public: string name; int age; class High_School_Student : public Student class College_Student :public Student class Young_Student :public Student 35
Arv Varför är arv användbart? Alternativ 3: Arv från gemensam basklass! class student string name; int Generell age; del class High_School_Student : public Student class College_Student :public Student class Young_Student :public Student Specifik del Specifik del Specifik del 36
Arv Varför är arv användbart? Alternativ 3: Arv från gemensam basklass! class student string name; int Generell age; del Vi har löst detta objektorienterat och med en klasshierarki Objekt av subklasserna har nu både den generella student-delen och den specifika delen! class High_School_Student : public Student class College_Student :public Student class Young_Student :public Student Specifik del Specifik del Specifik del 37
Arv Varför är arv användbart? Arv är bra för att det är lätt att utöka med ny funktionalitet och klasser Det är lätt att underhålla (Vi behöver bara ändra i de klasser som berörs) Vi kan skapa representationer av större saker än ett enskilt objekt 38
Arv Basklassen och härledda klasser Härledda klasser ärver från en basklass Det som är gemensamt ska hamna i basklassen Det som är specifikt för en klass hamnar i den härledda klassen Den som ärver får det som basklassen har När en härledd klass skapas så skapas det alltid tillsammans med basklassens delar Härledd klass Basklass 39
Arv student.h Hur skapar vi och använder basklasser och härledda klasser? class Student public: ; Student(string n, int a) : namen, agea string name; int age; void study() cout << Studerar << endl; OBS! Ej kompletta klasser. young_student.h class Young_Student : public Student public: ; Young_Student(string n, int a, bool w_b) : Student(n, a), want_breakw_b bool want_break; void study() cout << Jag vägrar!! << endl; main.cc int main() Student st Klas, 24; Young_Student y_st Oskar, 7, true; st = y_st; //Ok, ger slicing Student & st2 = y_st; //Ok, ger statisk bindning Student * st3 = &y_st; //Ok, ger statisk bindning Young_student y_st2 = st; //Fungerar ej! return 0; 40
Slicing En kort avstickare main.cc int main() Student st Klas, 24; Young_Student y_st Oskar, 7, true; st = y_st; //Ok, ger slicing Härledd klass Basklass return 0; 41
Slicing En kort avstickare main.cc int main() Student st Klas, 24; Young_Student y_st Oskar, 7, true; st = y_st; //Ok, ger slicing Härledd klass Basklass return 0; 42
Slicing En kort avstickare main.cc int main() Student st Klas, 24; Young_Student y_st Oskar, 7, true; st = y_st; //Ok, ger slicing Basklass Jobb well done! return 0; 43
Arv student.h Hur skapar vi och använder basklasser och härledda klasser? class Student public: ; Student(string n, int a) : namen, agea string name; int age; void study() cout << Studerar << endl; OBS! Ej kompletta klasser. young_student.h class Young_Student : public Student public: ; Young_Student(string n, int a, bool w_b) : Student(n, a), want_breakw_b bool want_break; void study() cout << Jag vägrar << endl; main.cc int main() Student st Klas, 24; Young_Student y_st Oskar, 7, true; st.study(); y_st.study(); return 0; 44
Arv student.h Hur skapar vi och använder basklasser och härledda klasser? class Student public: ; Student(string n, int a) : namen, agea string name; int age; void study() cout << Studerar << endl; OBS! Ej kompletta klasser. young_student.h class Young_Student : public Student public: ; Young_Student(string n, int a, bool w_b) : Student(n, a), want_breakw_b bool want_break; void study() cout << Jag vägrar << endl; main.cc int main() Student st Klas, 24; Young_Student y_st Oskar, 7, true; Student * curr_st &st; curr_st.study(); curr_st = &st; curr_st.study(); return 0; 45
Statisk bindning You get what you see I C++ används statisk bindning om inget annat ges Innebär att datatypen som anges i programkoden avgör vilken funktion som anropas int main() Student st Klas, 24; Young_Student y_st Oskar, 7, true; st.study(); y_st.study(); int main() Student st Klas, 24; Young_Student y_st Oskar, 7, true; Student * curr_st &st; curr_st.study(); curr_st = &st; curr_st.study(); Statisk bindning i båda fallen Medlemsfunktionen study anropas för den deklarerade datatypen return 0; return 0; 46
Statisk bindning You get what you see Varför vill vi komma runt detta? Är ju bara att deklarera rätt datatyp 47
Statisk bindning You get what you see Varför vill vi komma runt detta? Är ju bara att deklarera rätt datatyp int main() Young_Student y_st Oskar, 7, true; void student_info(student const & s) cout << Namn: << s.name; student_info(y_st); return 0; cout << Studieteknik: << s.study() << endl; 48
Statisk bindning You get what you see Varför vill vi komma runt detta? Är ju bara att deklarera rätt datatyp Skrivs study() för basklassen körs varje gång! int main() Young_Student y_st Oskar, 7, true; void student_info(student const & s) cout << Namn: << s.name; student_info(y_st); return 0; cout << Studieteknik: << s.study() << endl; 49
Polymorfi En sak kan vara många saker Vi vill kunna säga åt kompilatorn: Ta reda på mer om vad som egentligen gäller Statisk bindning Vad typen är deklarerad som Dynamisk bindning (som vi vill använda) Vad typen faktiskt pekar till 50
Polymorfi En sak kan vara många saker Dynamisk bindning får vi med nyckelordet virtual virtual kan vi deklarera en medlem i en basklass som subklasser kan skriva över I den härledda klassen lägger vi till override för de medlemmar som vi vill överlagra Override kollar i basklassen om funktionen är virtual Sedan används funktionen i härledda klassen istället för den i basklassen 51
student.h Polymorfi En sak kan vara många saker class Student public: ; Student(string n, int a) : namen, agea string name; int age; virtual void study() cout << Studerar << endl; OBS! Ej kompletta klasser. young_student.h class Young_Student : public Student public: ; Young_Student(string n, int a, bool w_b) : Student(n, a), want_breakw_b bool want_break; void study() override cout << Jag vägrar << endl; main.cc int main() Student st Klas, 24; Young_Student y_st Oskar, 7, true; Student * curr_st &st; curr_st.study(); curr_st = &st; curr_st.study(); return 0; 52
student.h Polymorfi En sak kan vara många saker class Student public: ; Student(string n, int a) : namen, agea string name; int age; virtual void study() cout << Studerar << endl; OBS! Ej kompletta klasser. young_student.h class Young_Student : public Student public: ; Young_Student(string n, int a, bool w_b) : Student(n, a), want_breakw_b bool want_break; void study() override cout << Jag vägrar << endl; main.cc int main() Student st Klas, 24; Young_Student y_st Oskar, 7, true; Student * curr_st &st; curr_st.study(); curr_st = &st; curr_st.study(); return 0; 53
student.h Polymorfi En sak kan vara många saker class Student public: ; Student(string n, int a) : namen, agea string name; int age; virtual void study() cout << Studerar << endl; OBS! Ej kompletta klasser. young_student.h class Young_Student : public Student public: ; Young_Student(string n, int a, bool w_b) : Student(n, a), want_breakw_b bool want_break; void study() override cout << Jag vägrar << endl; main.cc int main() Student st Klas, 24; Young_Student y_st Oskar, 7, true; Student * curr_st &st; curr_st.study(); curr_st = &st; curr_st.study(); return 0; 54
Polymorfi En sak kan vara många saker Polymorfi = att anta många olika former Ett anrop kan innebära att olika funktioner körs beroende på det objekt som används Varje objekt har ansvar för det den själv ska göra Bland det starkaste verktyget vi kan använda! 55
Polymorfi Abstrakta klasser (pure virtual) Lysande att vi kan få två implementationer, av samma funktion, för två olika klasser Det är däremot inte alltid vi vill att basklassen ska ha en implementation det ska kanske inte ens gå att skapa en instans av basklassen! Ta exemplet med Student. Basklassen ska samla de gemensamma delarna för härledda klasserna, fast det ska aldrig gå att bara skapa en Student. Lösning: gör klassen abstrakt 56
Polymorfi Abstrakta klasser (pure virtual) student.h class Student public: ; Student(string n, int a) : namen, agea string name; int age; virtual void study() = 0; OBS! Ej kompletta klasser. young_student.h class Young_Student : public Student public: ; Young_Student(string n, int a, bool w_b) : Student(n, a), want_breakw_b bool want_break; void study() override cout << Jag vägrar << endl; main.cc int main() //Student st Klas, 24; Young_Student y_st Oskar, 7, true; //st.study(); y_st.study(); return 0; 57
Polymorfi Abstrakta klasser (pure virtual) student.h class Student public: ; Student(string n, int a) : namen, agea string name; int age; virtual void study() = 0; OBS! Ej kompletta klasser. young_student.h class Young_Student : public Student public: ; Young_Student(string n, int a, bool w_b) : Student(n, a), want_breakw_b bool want_break; void study() override cout << Jag vägrar << endl; main.cc int main() Student st Klas, 24; Young_Student y_st Oskar, 7, true; //st.study(); y_st.study(); return 0; KOMPILERAR INTE 58
Polymorfi Abstrakta klasser (pure virtual) Pure virtual (= 0) följer alltid syntaxen virtual [returtyp] func_name() = 0; Räcker att en basklass har en funktion som är pure virtual för att klassen ska bli abstrakt. Detta tvingar alla härledda klasser att skapa en implementation av funktionen Det blir som ett avtal för att få ärva 59
Polymorfi Interface Om alla funktioner är satta till pure virtual (=0) blir klassen ett interface Ett interface är som att ärva en designspecifikation, eftersom härledda klasser måste implementera alla pure virtual funktioner 60
Polymorfi Interface class Playable_Object public: string playstring Spela upp ; void play() = 0; ; class Ipod: public Playable_Object public: void play() override; //Börjar spela musik ; class Video_Game: public Playable_Object public: void play() override; //Börjar spela spelet ; class Flute: public Playable_Object public: void play() override; //Börjar spela instrumentet ; 61
Using och delete En kort avstickare Det går att välja och vraka vilka medlemsfunktioner från basklasserna som ska finnas i den härledda klassen. Använda implementationen i basklassen: using [returtyp] Base_Class::func_name(); //Deklareras i härledda klassen Går aldrig att anropa denna funktionen för härledda klassen: [returtyp] func_name() = delete; //Deklareras i härledda klassen 62
student.h Polymorfi Att ta reda på den egentliga typen dynamisk typomvandling class Student public: ; Student(string n, int a) : namen, agea string name; int age; void study() cout << Studerar << endl; young_student.h class Young_Student : public Student public: Young_Student(string n, int a, bool w_b) : Student(n, a), want_breakw_b bool want_break; void take_break() cout << RAST!!! << endl; void study() cout << Jag vägrar << endl; ; void give_break(student * s) s->take_break(); return 0; OBS! Ej kompletta klasser. 63
student.h Polymorfi Att ta reda på den egentliga typen dynamisk typomvandling class Student public: ; Student(string n, int a) : namen, agea string name; int age; void study() cout << Studerar << endl; OBS! Ej kompletta klasser. young_student.h class Young_Student : public Student public: Young_Student(string n, int a, bool w_b) : Student(n, a), want_breakw_b bool want_break; void take_break() cout << RAST!!! << endl; void study() cout << Jag vägrar << endl; ; void give_break(student * s) s->take_break(); return 0; KOMPILERAR INTE 64
Polymorfi Att ta reda på den egentliga typen dynamisk typomvandling young_student.h class Young_Student : public Student public: Young_Student(string n, int a, bool w_b) : Student(n, a), want_breakw_b bool want_break; void take_break() cout << RAST!!! << endl; void study() cout << Jag vägrar << endl; ; OBS! Ej kompletta klasser. void give_break(student * s) Young_Student y_s dynamic_cast<young_student*>(s) ; if ( y_s!= nullptr) s->take_break(); else cout << No break for you! << endl; return 0; 65
Polymorfi Att ta reda på den egentliga typen dynamisk typomvandling dynamic_cast<datatype *>(variable) Returnerar en nullptr om om Datatype skiljer sig från datatypen i variable Returnerar en pekare till variable om datatyperna matchar OBS! Använd dynamic_cast sparsamt polymorfi gör oftast jobbet åt oss 66
Destruktorer En speciell medlemsfunktion Förra gången pratade vi om konstruktorer hur vi skapar ett objekt Vi har också destruktorer hur vi tar bort ett objekt Deklaration: ~Student(); Defintion: ~Student() //Här kan det hända grejer 67
Destruktorer En speciell medlemsfunktion En destruktor körs när ett objekt går ur scope eller när vi exempelvis utför delete på en pekare class Student public: Student(string n, int a) : namen, agea Student~() int main() Student * st new Young_Student Oskar, 7, true; delete y_st; ; string name; int age; return 0; ; 68
Destruktorer En speciell medlemsfunktion En destruktor körs när ett objekt går ur scope eller när vi exempelvis utför delete på en pekare class Student public: Student(string n, int a) : namen, agea Student~() int main() Student * st new Young_Student Oskar, 7, true; delete y_st; Härledd klass Basklass ; string name; int age; return 0; ; 69
Destruktorer En speciell medlemsfunktion Den yttre, härledda klassen, måste destrueras först. class Student public: ; Student(string n, int a) : namen, agea Student~() string name; int age; int main() Student * st new Young_Student Oskar, 7, true; delete y_st; return 0; ; Härledd klass Basklass 70
Destruktorer En speciell medlemsfunktion Den yttre, härledda klassen, måste destrueras först. Nu kommer Basklassen att destrueras class Student public: Student(string n, int a) : namen, agea Student~() int main() Student * st new Young_Student Oskar, 7, true; delete y_st; Härledd klass ; string name; int age; return 0; ; 71
Destruktorer En speciell medlemsfunktion Den yttre, härledda klassen, måste destrueras först. Måste sätta destruktorn i basklassen till virtual class Student public: Student(string n, int a) : namen, agea virtual Student~() int main() Student * st new Young_Student Oskar, 7, true; delete y_st; Härledd klass Basklass ; string name; int age; return 0; ; 72
Destruktorer En speciell medlemsfunktion Den yttre, härledda klassen, måste destrueras först. Måste sätta destruktorn i basklassen till virtual class Student public: ; Student(string n, int a) : namen, agea virtual Student~() string name; int age; int main() Student * st new Young_Student Oskar, 7, true; delete y_st; return 0; ; Basklass 73
Destruktorer En speciell medlemsfunktion Den yttre, härledda klassen, måste destrueras först. Måste sätta destruktorn i basklassen till virtual class Student public: ; Student(string n, int a) : namen, agea virtual Student~() string name; int age; int main() Student * st new Young_Student Oskar, 7, true; delete y_st; return 0; ; 74
Synlighet Public, private och protected I en klass kan vi sätta synlighet på medlemmarna public = möjligt att komma åt utanför klassen Private = går inte att komma åt utanför klassen Hur blir det 75
Synlighet Public, private och protected I en klass kan vi sätta synlighet på medlemmarna public = möjligt att komma åt utanför klassen private = går inte att komma åt utanför klassen Hur blir det med arv? Ibland vill vi att härledda klasser ska komma åt medlemmar, fast ingen utanför klass-familjen ska komma åt dem 76
Synlighet Public, private och protected student.h class Student public: Student(string n, int a) : namen, agea void study() cout << Studerar << endl; protected: string name; int age; ; young_student.h class Young_Student : public Student public: Young_Student(string n, int a, bool w_b) : Student(n, a), want_breakw_b void study() cout << Jag vägrar!! << endl; private: bool want_break; ; 77
Synlighet Public, private och protected i arvet Har du tänkt på varför public behövs vid arv? class Young_Student : public Student Vad händer om vi skriver något annat? public: medlemmar i basklasen behåller deklarerat skydd i härledd klass protected: public medlemmar i basklassen blir protected i härledd klass private: alla medlemmar i basklassen blir private i härledd klass Om inget deklareras väljs private arv standard 78
UML Unifiedmodeling language Blir en massa relationer att hålla koll på Vore det inte trevligt om vi enkelt kan skapa en grafisk representation av en klasshierarki? 79
UML Unifiedmodeling language UML är ett grafiskt språk som används för att beskriva relationen mellan klasser i objektorienterade system Industristandard idag 80
UML Beskrivning av en klass + public - private #protected italic abstrakt Car - model: String - gear: int - owner: String + startengines() + driveforward() + reverse() + putingear(int) Klassnamn Attribut Funktioner 81
Arv ett stort exempel Olika metoder att bygga en klasshierarki En klasshierarki är en representation som vi själva skapar Vi behöver gå från idé om en representation till klasser Två vanliga tillvägagångsätt: Top-down Bottom-up 82
Arv ett stort exempel Olika metoder att bygga en klasshierarki Hogwarts behöver digitaliseras Det finns studenter, lärare, trollformler och Hogwarts självt Hur modellerar vi detta? (Top-down) 83
Arv ett stort exempel Olika metoder att bygga en klasshierarki Wizard - name: String - age: int + sayhello() + castspell() Hogwarts + sortstudent(student) + magiclessons() + presentstudents() 84
Arv ett stort exempel Olika metoder att bygga en klasshierarki Wizard - name: String - age: int + sayhello() + castspell() 0..* 1 Hogwarts - students: Student[] - teachers: Teacher[] Student - home: String + practicespell() Teacher - course: String + teachspell() 1 + sortstudent(student) + magiclessons() + presentstudents() 0..* 85
Arv ett stort exempel Olika metoder att bygga en klasshierarki Spell - name: String 1 1 Wizard - name: String - age: int - favouritespell: Spell + caston(wizard) + sayhello() + castspell() 0..* 1 Hogwarts - students: Student[] - teachers: Teacher[] Student - home: String + practicespell() Teacher - course: String + teachspell() 1 + sortstudent(student) + magiclessons() + presentstudents() 0..* 86
Arv ett stort exempel Olika metoder att bygga en klasshierarki Spell # name: String 1 1 Wizard - name: String - age: int - favouritespell: Spell + caston(wizard) + sayhello() + castspell() 0..* 1 Hogwarts - students: Student[] - teachers: Teacher[] Expelliarmus + caston(wizard) Student - home: String + practicespell() Teacher - course: String + teachspell() 1 + sortstudent(student) + magiclessons() + presentstudents() 0..* 87
Arv ett stort exempel Olika metoder att bygga en klasshierarki Spell # name: String 1 1 Wizard - name: String - age: int - favouritespell: Spell + caston(wizard) + sayhello() + castspell() 0..* 1 Hogwarts - students: Student[] - teachers: Teacher[] Expelliarmus + caston(wizard) Lumos + caston(wizard) Student - home: String + practicespell() Teacher - course: String + teachspell() 1 + sortstudent(student) + magiclessons() + presentstudents() 0..* 88
www.liu.se