TDDE10 TDDE11, 725G90 Objektorienterad programmering i Java, Föreläsning 3 Erik Nilsson, Institutionen för Datavetenskap, LiU På denna föreläsning: Arv Polymorf UML (klassdiagram) 1
Arv Möt tre studenter Gymnasiestudenten Anna Högskolestudenten Harry Impulsive Ivar Alla tre har vissa gemensamma egenskaper (både attribut och operationer) Har ett skåp. Gillar att lösa problem med penna och papper Har ett antal avklarade HP. Gillar att lösa problem med en väl skriven programmeringsalgoritm Gillar huvudbonader och att gå ut på rast Vägrar att lösa problem. 2
Arv (2) Imperativ lösning class Student { - Alternativ 1, monsterklass! class Main { String name; String type; int age; Generell Specifik Student stud = new Student( Harry, College, 27); Specifik Specifik if (stud.type (stud.gettype().equals( College )) == { { // stud.collagespecifics(); else if (stud.type (stud.gettype().equals( Young )) == { { // stud.youngspecifics();... FULLSTÄNDIGA UPPRÄKNINGAR ÖVERALLT! SVÅRT ATT UNDERHÅLLA FÖR DÅLIGT! SVÅRT ATT UTÖKA 3
Arv (3) Imperativ lösning - Alternativ 2 separata klasser! class HighShoolStudent class CollegeStudent class YoungStudent Generell Generell Generell Specifik Specifik Specifik Bättre! Nu ansvarar klassen själv för olika funktionalitet, men... och, hård typning kan ställa till det för oss... KODDUPLICERING 4
Arv (4) Bästa av två världar - Gemensam superklass class Student Generell Dessa klasser ärver från Student! class HighShoolStudent class CollageStudent class YoungStudent extends Student extends Student extends Student Specifik Specifik Specifik Objekt av dessa subtyper (subklasser) har nu både den generella student-en och den specifka en! 5 Men kommer endast åt det som är public eller protected.
Arv(5) Vi har nu löst detta objektorienterat med en klasshierarki. Alla studenter har ett namn och en ålder Alla studenter bör kunna studera och lösa uppgifter. Den gemensam klassen Student får ha dessa variabler och metoder. public class Student { private int age; private String name; public Student(String name, int age) { this.name = name; this.age = age; public void study() { System.out.println("I am studying very hard."); public String solveproblem(string problem) { System.out.println( I give up!"); return nothing"; 6
Arv(6) Vi lägger till saker som är specifkt för gymnasieelever i denna klass. En gymnasieelev är en Student. => Arv! Vi kan ändra beteenden från Student genom överskuggning. public class HighSchoolStudent extends Student { private String locker; public HighSchoolStudent(String n, int a, String l) { super(n, a); // Vi skickar vidare n och a till superklassens konstruktor! this.locker = l; public Student(String name, int age) { this.name=name; this.age=age; // overriding solveproblem with my implementation public String solveproblem(string problem) { System.out.println( Solving with pen and paper. ); return The answer is 84 / 2 ; 7
Arv(7) Hur deklarerar vi nu variabler av dessa typer? Hur instansierar vi objekten? public static main(string[] args) { Student stud1 = new Student( Frankie, 7); HighSchoolStudent stud2 = new HighSchoolStudent( Anna, 18, Lots of junk ); Student stud3 = new HighSchoolStudent( Laura, 17, Books ); HighSchoolStudent stud4 = new Student( Bert, 14); En variabel av super-typ kan hålla I en instans av sub-typ! Eftersom HSStudent är en student. Blir kompileringsfel! En Student är inte (nödvändigtvis) en HSStudent. 8
Arv(8) Vad kommer ut på skärmen? public static main(string[] args) { Student stud1 = new Student( Frankie, 22); class Student void study() { print( studying hard ); void solveproblem() { print( give up! ); stud1.study(); stud1.solveproblem(); Student stud3 = new HighSchoolStudent( Laura, 17, Books ); stud3.study(); stud3.solveproblem(); stud1 = stud3; stud1.solveproblem(); Exakt vilken metod som anropas bestäms först vi körning. Vi följer referensen och kör metoden i den instans vi hamnar i! POLYMORFI! class HighShoolStudent extends Student void solveproblem() { print( pen & paper ) 9
Arv(9) Vad är effekten av polymorf (eller polymorfsm)? Vi går från detta... public dox(someclass obj) { public doy(someclass obj) { public doz(someclass obj) { if (obj.) { // X behavior 1 else if (obj.) { // X behavior 2 else if (obj.) { // X behavior 3 else if (obj.) { // X behavior 4 else if (obj.) { // X behavior 5 else if (obj.) { // X behavior 6 if (obj.) { // Y behavior 1 else if (obj.) { // Y behavior 2 else if (obj.) { // Y behavior 3 else if (obj.) { // Y behavior 4 else if (obj.) { // Y behavior 5 else if (obj.) { // Y behavior 6 if (obj.) { // Z behavior 1 else if (obj.) { // Z behavior 2 else if (obj.) { // Z behavior 3 else if (obj.) { // Z behavior 4 else if (obj.) { // Z behavior 5 else if (obj.) { // Z behavior 6 10
Arv(10) Till detta: Class SuperObj public void dox() { public void doy() { public void doz() {... Class ObjWithBehavior1 Class ObjWithBehavior2 Class ObjWithBehavior3 Class ObjWithBehavior4 public void dox() { // X Behavior 1 public void doy() { // Y Behavior 1 public void doz() { // Z Behavior 1 public void dox() { // X Behavior 2 public void doy() { // Y Behavior 2 public void doz() { // Z Behavior 2 public void dox() { // X Behavior 3 public void doy() { // Y Behavior 3 public void doz() { // Z Behavior 3 public void dox() { // X Behavior 4 public void doy() { // Y Behavior 4 public void doz() { // Z Behavior 4 Class ObjWithBehavior5 Class ObjWithBehavior6 Class ObjWithBehavior7 public void dox() { // X Behavior 5 public void doy() { // Y Behavior 5 public void doz() { // Z Behavior 5 public void dox() { // X Behavior 6 public void doy() { // Y Behavior 6 public void doz() { // Z Behavior 6 public void dox() { // X Behavior 7 public void doy() { // Y Behavior 7 public void doz() { // Z Behavior 7 11
Arv(11) Några termer: Superklass, Basklass Subklass, härledd klass (en. Derived class) Överskugga (en. Override) "Föräldraklassen" En klass som ärver från en superklass Implementera eller ersätt en metod från en superklass (eller ett interface) Polymorf Att ett anrop kan innebära olika beteenden under körning p.g.a. arv och överskuggning. HighSchoolStudent, CollegeStudent och YoungStudent ärver ifrån Student Subklasser till Student får överskugga metoderna study() och solveproblem(). För att komma åt superklassen från subklassen, använd super Förbjuda subklassning och överskuggning? Använd fnal 12
Arv(12) @Override Är en Java annotation. En specielly symbol som lägger till ett attribut för t.ex en metod. Just denna symbol påvisar att en metod överskuggar en av superklassens metoder. T.ex. i HighSchoolStudent: @Override public String solveproblem(string problem) { System.out.println( Solving with pen and paper. ); return The answer is 84 / 2 ; Det visar, både för oss, och för kompilatorn att överskuggning sker. Om något inte stämmer (t.ex. namnet på metoden), blir det kompileringsfel. => Bra praxis! 13
Typkontroll Man kan kontrollera ett objekts klass under körning med operatorn instanceof. public static main(string[] args) { Student stud1 = new...... if (stud1 instanceof HighSchoolStudent) { System.out.println( Solving with pen and paper ); else if (stud1 instanceof CollegeStudent) { System.out.println( Solving with OOP ); else if (stud1 instanceof YoungStudent) { System.out.println( I refuse! ); Bör användas MYCKET SPARSAMT. Jämför med vår polymorflösning: stud1.solveproblem(); 14
Konvertering (castning) I vissa lägen kan det vara rimligt att göra en typkontroll och sedan konvertering. T.ex. om det är något som bara en subklass kan göra. if (stud1 instanceof HighSchoolStudent) { HighSchoolStudent hs = (HighSchoolStudent)stud1; hs.openlocker(); Samma här: använd MYCKET sparsamt. Kan det snarare vara så att denna if-sats skall ansvaras för i HighSchoolStudent-klassen? Då skulle vi slippa instanceof och castning. 15
Object Alla klasser ärver automatiskt från klassen Object, direkt eller indirekt Visar på att arv i flera led är möjligt Några metoder som fnns i klassen Object boolean equals(object other) Object clone() String tostring() void fnalize() Dessa metoder behöver ibland överskuggas 16
UML Unifed Moling Language Ett grafskt språk för att beskriva objektorienterade system i alla steg i programvarutvecklingen De-fakto industristandard idag I den här kursen koncentrerar vi oss på klassdiagram 17
UML Beskrivning av en klass + public - private # protected ~ package private understruken static Italic abstrakt / derived Car - String mo - int gear - String owner + startengines() + driveforward() + reverse + putingear(int) Klassnamn Attribut Metoder 18
UML Beskrivning av relationer mellan klasser Association A använder en B Aggregation A har en B OBS vag defnition inom Java, undvik att använda Komposition A äger en B Generalisering (arv) A ärver från B (A kan användas som en B) Realisering (interface) A implementerar B Beroende A är beroende av B Multiplicitet exempel: En A använder en eller flera B 19
UML Exempel: UML-beskrivning av Studentklasserna Student +study() +solveproblem(string problem) : String HighSchoolStudent - String Locker +solveproblem(string problem) : String +openlocker() YoungStudent +study() +solveproblem(string problem) : String CollegeStudent - int HP +solveproblem(string problem) : String +gethp(): int 20