Principles of subclasses. Objekt-orienterad programmering och design Alex Gerdes, 2018

Relevanta dokument
Principles of subclasses Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

Föreläsning 5. När skall man använda implementationsarv? När skall man använda implementationsarv?

Generics och polymorfism. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Generics och polymorfism. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

Föreläsning 5. När skall implementationsarv användas? The Open-Closed Principle (OCP) Liskov Substitution Principle (LSP)

Föreläsning 5. När skall man använda implementationsarv?

Subtyping, co- och contra-variance. Objekt-orienterad programmering och design Alex Gerdes, 2016

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

UML. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Classes och Interfaces, Objects och References Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Static vs Dynamic binding Polymorfism. Objekt-orienterad programmering och design Alex Gerdes, 2016

Classes och Interfaces, Objects och References, Initialization

Generic type declarations. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Static vs Dynamic binding Override vs Overload. Objekt-orienterad programmering och design Alex Gerdes och Sólrún Halla Einarsdóttir, 2018

Objekt-orienterad programmering och design. DIT953 Niklas Broberg, 2018

Återanvändning. Två mekanismer. Nedärvning av egenskaper (inheritance) Objekt komposition

Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Mutability och State. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

Design Patterns. Objekt-orienterad programmering och design Alex Gerdes, 2016

TDA550 Objektorienterad programvaruutveckling IT, forts. kurs Övning vecka 2

Objekt-orienterad Programmering och Design. TDA551 Alex Gerdes, HT-2016

Subtyping, co- och contra-variance. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016 Johannes Åman Pohjola, 2017

Separation of Concern. Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016 Johannes Åman Pohjola, 2017

Java-syntax (arv) Exempel: public class Crow extends Bird {... } Jämför med Lab 1: public class FirstApp extends Frame {... }

F8 - Arv. ID1004 Objektorienterad programmering Fredrik Kilander

Separation of Concern. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

Outline. Objektorienterad Programmering (TDDC77) Signatur. Klassen calculator. Överlagring (overloading) Arv (inheritance) Ahmed Rezine

Föreläsning 8 - del 2: Objektorienterad programmering - avancerat

Objektorienterad Programmering (TDDC77)

Subtyping och variance. Objekt-orienterad programmering och design Alex Gerdes, 2018

Dependencies High cohesion, low coupling. Objekt-orienterad programmering och design Alex Gerdes, 2018

Typhierarkier del 1 Gränssnitt, ärvning mellan gränssnitt, ärvning mellan klasser

Sammanfattning och Tentamensinfo Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

Föreläsning 8. Arv. Arv (forts) Arv och abstrakta klasser

Grundläggande programmering, STS 1, VT Sven Sandberg. Föreläsning 14

Instuderingsuppgifter läsvecka 2

Kursombud. Objektorienterad modellering och diskreta strukturer / design. Agile? Designprinciper EDAF10 EDA061. Lennart Andersson. Grupper för projekt

TDDC76 - Programmering och Datastrukturer

Arv och klassbibliotek

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Erik Nilsson, Institutionen för Datavetenskap, LiU

Objektorienterad programmering. Grundläggande begrepp

Föreläsning 15: Repetition DVGA02

Objektorientering - Arv och polymorfi. Eric Elfving Institutionen för datavetenskap

Outline. Objektorienterad Programmering (TDDC77) Åsidosättning. Signatur. Åsidosättning. Abstrakta klasser. Ahmed Rezine.

Objekt-orienterad Programmering och Design. TDA552 Alex Gerdes, HT-2018

JUnit. Ska kompletteras med kodexempel på JUnit. DD2385 Programutvecklingsteknik Några bilder till föreläsning 12 21/5 2012

Dependencies High cohesion, low coupling. Objekt-orienterad programmering och design (DIT953) Niklas Broberg, 2018

Design Patterns. Objekt-orienterad programmering och design Alex Gerdes, 2018

Arv. Fundamental objekt-orienterad teknik. arv i Java modifieraren protected Lägga till och modifiera metoder med hjälp av arv Klass hierarkier

Föreläsning 3 Arvsmekanismen Variabler och typer Typer och subtyper

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

Modulär design Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Lösningsförslag till tentamen

Typecasting - primitiva typer. Innehåll. DoME klasser

Arv. Objektorienterad och komponentbaserad programmering

TDDE10 TDDE11, 725G90. Objektorienterad programmering i Java, Föreläsning 3 Erik Nilsson, Institutionen för Datavetenskap, LiU

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 2 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Design Patterns Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2017

Innehåll. dynamisk bindning. och programmering CRC) u Arv, polymorfi och

Lösningsförslag. 1 Lösningsförslag. Uppgift 1

Modulär design. Objekt-orienterad programmering och design (DIT953) Niklas Broberg / Johannes Åman Pohjola, 2018

TDDD78, TDDE30, 729A Typhierarkier del 2 Vad krävs? Hur fungerar det?

Viktiga programmeringsbegrepp: Kontrakt

Arv (Inheritance) Multipelt arv finns i verkligheten. Överskuggning, metodbindning. Läsanvisning: ! Arv! Object, instanceof! Relationer!

Introduktion och OO. Objekt-orienterad Programmering och Design (TDA552) Alex Gerdes, HT-2018

Lösningar till tentamen i EDAF25

Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }

public class BoundedCounter {

Ärvning av implementation. Ärvning av implementation, inklusive abstrakta klasser Hur ska vi ärva? När ska vi ärva?

Imperativ programmering. Föreläsning 4

Objektorienterad Programkonstruktion. Föreläsning 2 2 nov 2016

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

Tentamen Programmering fortsättningskurs DIT950

Idag. Exempel, version 2. Exempel, version 3. Ett lite större exempel

DAT043 - Föreläsning 7

Lösningsförslag till exempeltenta 2

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 11 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Objektorienterad Programkonstruktion. Föreläsning 4 8 nov 2016

2I1049 Föreläsning 5. Objektorientering. Objektorientering. Klasserna ordnas i en hierarki som motsvarar deras inbördes ordning

Tentamen. 2D4135 vt 2004 Objektorienterad programmering, design och analys med Java Torsdagen den 3 juni 2004 kl

Idag. statiska metoder och variabler. private/public/protected. final, abstrakta klasser, gränssnitt, delegering. wrapper classes

Objektorienterad Programmering (OOP) Murach s: kap 12-16

TDA550 Objektorienterad programvaruutveckling IT, forts. kurs Övning vecka 3

Föreläsning 9: Arv och UML

Objekt, klasser. Tillstånd Signatur Kommunikation Typ. Fält, parametrar och lokala variabler. Konstruktorer Metoder DAVA15

Vad handlar kursen om? Algoritmer och datastrukturer. Vad handlar kursen om? Vad handlar kursen om?

TDA550 Objektorienterad programmering, fortsättningskurs. Föreläsning 1. Introduktion Variabler och typer

Objektorienterad Programmering (TDDC77)

Föreläsning 13 Innehåll

Arv innebär att man skapar en ny klass (subklass) utifrån en redan existerande klass (superklass, basklass).

OOP Objekt-orienterad programmering

Outline. Objektorienterad Programmering (TDDC77) Laborationsserie del två. Vad händer under HT2. Introduktion HT2 UML.

Tentamen LÖSNINGSFÖRSLAG. c) Tilldelningen C x = new D() ger kompileringsfel eftersom klassen D är abstrakt.

Repetition av OOP- och Javabegrepp

Abstrakt klass. DD2385 Programutvecklingsteknik Några bilder till föreläsning 4 7/ Exempel: Implementation av Schackpjäser.

Vad kännetecknar en god klass. Vad kännetecknar en god klass. F12 Nested & Inner Classes

Lösningsförslag till exempeltenta 1

Undantag, Sammanfattning och Tentamensinfo. Objekt-orienterad programmering och design Alex Gerdes, 2016

Objektorienterade programmeringsspråk. Objektorienterade språk. Den objekt-orienterade modellen. Jämför med icke-oo

UML. Översikt UML. Relationer mellan klasser. A är ett aggregerat av B:n. Kontor aggregat av Enheter. 12 olika diagramtyper, bl.a.

Transkript:

Principles of subclasses Objekt-orienterad programmering och design Alex Gerdes, 2018

Implementation inheritance Subclassing, eller implementation inheritance (implementationsarv), ger oss två fördelar: Polymorfism Ett objekt av en subclass kan användas som om det var ett objekt av sin superclass. Ger flexibilitet, Plug-n-play ; kan e.g. arbeta med listor av objekt med superklassen som statisk typ, som vid run time kan vara av antingen superclass eller (någon) subclass. Återanvändning av kod (code reuse) Definiera gemensamma metoder i superklassen som kan ärvas av dess subclass(es). Don t repeat yourself, ingen cut-n-paste. Ger ett enda ställe för förändring vid behov maintainability.

Polymorfism reclaimed Polymorfism kan åstadkommas med hjälp av ett interface istället: Polygon + paint(graphics) : void + overlaps(polygon) : boolean IPolygon <<interface>> + paint(graphics) : void + overlaps(polygon) : boolean Rectangle + overlaps(rectangle) : boolean Polygon + paint(graphics) : void + overlaps(polygon) : boolean Rectangle + paint(graphics) : void + overlaps(polygon) : boolean + overlaps(rectangle) : boolean

Code reuse reclaimed Code reuse kan åstadkommas med hjälp av delegering istället: Polygon + paint(graphics) : void + overlaps(polygon) : boolean IPolygon <<interface>> + paint(graphics) : void + overlaps(polygon) : boolean Rectangle - parent : Polygon + paint(graphics) : void + overlaps(polygon) : boolean + overlaps(rectangle) : boolean class Rectangle { } private Polygon parent = public boolean overlaps(polygon other) { parent.overlaps(other); } Ärvd metod via delegering

Live code

Motivation Antag att vi har behov av att utnyttja polymorfism har behov av att återanvända kod Är det då fritt fram att använda implementation inheritance? Ledande fråga: Svaret är nej, det är inte riktigt så enkelt.

En person är en hund Dog - name : String - birthdate : Date + getname() : String + getbirthdate() : Date Vi (antar att vi) har behov av polymorfism (e.g. en lista som innehåller både hundar och personer). Vi har återanvändning av kod. Person - employer : Company Så vad är problemet?? + getemployer() : Company

Konceptuell Is-A Även om lösningen rent tekniskt åstadkommer det vi behöver, så är det inte en konceptuellt bra lösning. En person är inte en hund. Kod baserat på antagandet att en person är en hund kommer vara mycket förvirrande. Vi tappar simplicity, readability, maintainability. Slutsats: Använd aldrig implementation inheritance om det inte föreligger ett faktiskt, konceptuellt delmängds -förhållande mellan sub- och superclass.

Motivation andra försöket Antag att vi har behov av att utnyttja polymorfism har behov av att återanvända kod har ett konceptuellt Is-a -förhållande Är det fritt fram att använda implementation inheritance nu då? Svar: Nej

Roller i ett rollspel Player User - username : String + getusername() : String GameMaster Vi har behov av polymorfism (e.g. en lista av alla användare oavsett typ). Vi har kod vi vill återanvända. Både spelare och spelledare är konceptuellt användare. + playermethod() : void + gamemastermethod() : void Så vad är problemet??

Stabil Is-A med unika positioner En användare kan i vissa sammanhang vara en spelare, i andra sammanhang en spelledare. Hur representerar vi detta? Om vi använder ett Player-objekt för att representera användaren i rollen som spelare, och ett GameMaster-objekt för att representera användaren i rollen som spelledare, då kommer dessa två objekt att båda ärva all data (e.g. username) från User. Denna data dupliceras över två separata objekt. Ändras datan måste den uppdateras på båda ställena för att inte få inkonsekvens problem!

Delegering för roller Vid delegering kan samma User-objekt återanvändas för båda rollerna, vilket undviker problemet. Slutsats: Använd inte implementation inheritance för att representera roller som objekt kan ha använd alltid delegering i sådana fall. I en korrekt subclass-hierarki återfinns varje objekt på ett enda ställe, och ändras inte. :Player user = :User username = agerdes :GameMaster user =

Motivation tredje försöket Antag att vi har behov av att utnyttja polymorfism har behov av att återanvända kod har ett konceptuellt och stabilt Is-a -förhållande med unika positioner Är det fritt fram att använda implementation inheritance nu då? Svar: Nej

Squaring off Rectangle - width : int - height : int + getwidth() : int + getheight() : int + getarea() : int + setwidth(int) : void + setheight(int) : void + setsize(int,int) : void Square + setsize(int) : void Vi har behov av polymorfism. Vi har kod vi vill återanvända. En kvadrat är konceptuellt sett en rektangel, och kommer alltid att vara det (stabilt förhållande). Så vad är problemet??

Två perspektiv på subklasser Object Object Rectangle Rectangle Square Square Fokus på delmängder: Vad ett objekt är. Fokus på beteende: Vad ett objekt kan.

Delmängder av många anledningar, subklasser endast av en En delmängd kan uttryckas som en property: Om B Í A, då har vi B = { x x Î A, P(x) } för något P. Av alla objekt i A är det bara de som uppfyller P som är i B. Sådana properties kan komma i otaliga former endast en form av property lämpar sig för subklassning: när P(x) indikerar att elementen i B kan något som elementen i A inte kan. Elementen i B har utökat beteende jämfört med elementen i A.

Dåliga anledningar Några exempel på konceptuella Is-a -relationer som inte lämpar sig för subclassing: P(x) indikerar att x har begränsat beteende, i.e. inte kan något som övriga kan. E.g. en åskådare i ett dataspel är en spelare som inte kan agera. P(x) indikerar en extern begränsning. E.g. en kvadrat är en rektangel som måste ha lika långa sidor. P(x) indikerar ett temporärt tillstånd. E.g. en öppen fil är en fil med temporärt utökat beteende, e.g. läsa från och skriva till. Mer om hur vi hanterar tillstånd (state) i block 6-1.

Motivation fjärde försöket Antag att vi har behov av att utnyttja polymorfism har behov av att återanvända kod har ett konceptuellt och stabilt Is-a -förhållande med unika positioner har ett publikt gränssnitt för subklassen som är en utökning av superklassens Är det fritt fram att använda implementation inheritance nu då? Svar: Fortfarande nej

Forcerat gränssnitt Rectangle - width : int - height : int + getwidth() : int + getheight() : int + getarea() : int + setwidth(int) : void + setheight(int) : void + setsize(int,int) : void class Square extends Rectangle { @Override public void setsize(int w, int h) { this.setsize(w); } // Square + setsize(int) : void }

Live code

Liskov Substitution Principle If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T. (Barbara Liskov) S är en äkta subtyp till T endast om, för varje publik metod som finns i både S och T: S s metod godtar alla värden som T s metod godtar S gör alla beräkningar på denna indata som T gör (och kanske fler).

Motivation femte försöket Antag att vi har behov av att utnyttja polymorfism har behov av att återanvända kod har ett konceptuellt och stabilt Is-a -förhållande med unika positioner har ett publikt gränssnitt för subklassen som är en utökning av superklassens har ett publikt beteende för subklassen som är en utökning av superklassens Är det fritt fram att använda implementation inheritance nu då? Svar: Ja, men

Slutsatser För att implementation inheritance alls ska vara lämpligt: Ett konceptuellt Is-a -förhållande måste föreligga. Om inte använd ett gemensamt interface och/eller delegering. Vi måste ha (möjligen framtida) behov av polymorfism. Om inte använd enkel delegering. Vi måste ha behov av att återanvända kod. Om inte använd interfaces. Subklassens publika gränssnitt ska inkludera superklassens. Om inte bryt ut det gemensamma gränssnittet till ett interface som båda implementerar. Subklassen ska lägga till extra beteenden och beräkningar, inte ändra redan befintliga. Om inte hitta minsta gemensamma nämnare i beteende och gör denna antingen till (abstrakt) superklass för båda, eller en (privat) klass som båda delegerar till.

Med det sagt Nu är det fritt fram att använda implementation inheritance! men fortfarande inte nödvändigt, eller ens rekommenderat. Fundera alltid ett varv extra om det är motiverat att använda interfaces och/eller delegering istället är alltid: mer flexibelt du kan bilda explicita relationer mellan objekten som inte begränsas av subclass-superclass. mer precist du kan välja exakt de delar som behövs för code reuse och/eller polymorfism. men mer verbost kan göra koden mer svårläslig. Glöm inte att du bara har en möjlighet till att välja superclass (single inheritance), men kan implementera obegränsat antal interfaces.

Live code

Starkt beroende Implementation inheritance innebär ett starkt beroende på superklassen. Starka beroenden är dåliga för våra mål: extensibility, reusability, maintainability. Mycket mer om beroenden fr o m block 4-2. Favor composition over inheritance.

What s next Block 3-1: Subtyping, co- och contra-variance