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

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

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

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

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

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

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

Classes och Interfaces, Objects och References, Initialization

Classes och Interfaces, Objects och References 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

DAT043 - föreläsning 8

Lambdas. (och fler design patterns) Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2017

Kopiering av objekt i Java

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

Begreppet subtyp/supertyp i Java. Mera om generik. Generik och arv. Generik och arv. Innehåll

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

Typecasting - primitiva typer. Innehåll. DoME klasser

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

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

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

Ett problem. Kontrollstrukturer och arrayer. Arrayer. Lösningen. Arrayer och hakparanteser. Exempel int[] results; results = new int[10]; // 0..

Objektorienterad programmering med Java, Generics

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

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

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

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

Generisk klass med typparameter Inre klass - ListIterator

Arrayer. results

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

Subklasser och arv Inledning till grafik (JFrame och JPanel). Något om interface. Objektorienterad programvaruutveckling GU (DIT011) Subklasser

Exempel. Arrayer. Lösningen. Ett problem. Arrayer och hakparanteser. Arrayer

Innehåll. Pekaren this Självreferens. Klasser Resurshantering, representation. Överlagring av operatorer. Överlagring av operatorer

OOP Objekt-orienterad programmering

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

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

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

Objektorienterad programmering Föreläsning 12. Copyright Mahmud Al Hakim

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

OOP Objekt-orienterad programmering

DAT043 - Föreläsning 7

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

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.

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

F9 - Polymorfism. ID1004 Objektorienterad programmering Fredrik Kilander

"Är en"-relation. "Har en"-relation. Arv. Seminarium 2 Relevanta uppgifter. I exemplet Boll från förra föreläsningen gällde

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

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

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

UML. Klassdiagr. Abstraktion. Relationer. Överskugg. Överlagr. Aktivitetsdiagram Typomv. Typomv. Klassdiagr. Abstraktion. Relationer.

Innehåll. 1 Kort om dynamisk polymorfism. 2 Arv i C++ 3 Multipelt arv. 4 Något om statisk polymorfism. class Container {

Sammansatta datatyper Generics: Parametrisk polymorfism

Instuderingsuppgifter läsvecka 6 - LÖSNINGAR

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

Föreläsning 3 Innehåll. Generiska klasser. Icke-generisk lista ArrayList, skiss av implementering. Icke-generisk lista Risk för fel

Objekt-orienterat vs funktionellt Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2016

Dynamisk bindning och polymorfism

TENTAMEN: Objektorienterad programmering. Läs detta! Skriv din tentamenskod på varje blad (så att vi inte slarvar bort dem).

Tentamen för TDA540 Objektorienterad Programmering. Institutionen för Datavetenskap CTH HT-17, TDA540. Dag: , Tid:

Laboration 1: Figurer i hierarki

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

Länkade strukturer, parametriserade typer och undantag

Föreläsning 13 Innehåll

Objektorienterad programmering Föreläsning 10. Copyright Mahmud Al Hakim Sorteringsalgoritmer

Java, klasser, objekt (Skansholm: Kapitel 2)

Innehåll. Konstruktorer vid arv Regler för basklassens konstruktor. Konstruktorer vid arv. Konstruktorer vid arv. Konstruktorer vid arv

Föreläsning 4. Polymorfism. Polymorfism Dynamisk bindning Inkapsling Information hiding Access-metoder och mutator-metoder

Föreläsning 8 Programmeringsteknik och Matlab 2D1312/2D1305. Klass Object, instans av klass public/private Klassvariabler och klassmetoder

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

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

DAT043 Objektorienterad Programmering

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

Klasshierarkier - repetition

Föreläsning 2. Länkad lista och iterator

Föreläsning 2, vecka 8: Repetition

Abstrakt datatyp. -Algoritmer och Datastrukturer- För utveckling av verksamhet, produkter och livskvalitet.

Lösningsförslag till tentamen för TDA540 Objektorienterad Programmering

Mera om generik. Innehåll. Generik och arv Wildcards Vektorer och generik Generiska metoder. EDA690 (Mera om generik) HT / 24

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

Konstruktion av klasser med klasser

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

Kungl. Tekn. Högskolan Förel 1, bild 1 Föreläsning 1: Introduktion ffl Kursinnehåll ffl Javarepetition ffl Referenser ffl Nyckelordet static ffl Klass

Modeller, Objekt och Klasser

Polymorfi. Objektorienterad och komponentbaserad programmering

F8 - Arv. ID1004 Objektorienterad programmering Fredrik Kilander

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

Introduktion till arv

Lösningar för tenta 3 DAT043,

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

TENTAMEN. Kurs: Objektorienterad programmeringsmetodik 5DV133 Ansvarig lärare: Anders Broberg. VT-13 Datum: Tid: kl

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

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

Repetition av OOP- och Javabegrepp

Objektorienterad Programmering (TDDC77)

Introduktion till Java

Sammansatta datatyper Generics: Parametrisk polymorfism

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

Objekt-orienterat vs funktionellt Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2017

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

Repetition av OOP- och Javabegrepp

Målen med OOSU. Objektorienterad programmering. Objektorienterad programmering. Karlstads Universitet, Johan Öfverberg 1

Transkript:

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

Typer Java har två sorters typer primitiva typer och referens-typer. Primitiva typer är typer för värden: int, float etc. Java har två sorters referens-typer array types samt class or interface types. Arrayer är ett specialfall. De bor på heapen, vi arbetar med dem via referenser, de är i praktisk mening objekt men typerna ser lite speciella ut. Vi pratar här om statiska typer de som används av typ-checkaren under kompilering.

Subtyper En typ A (e.g. Triangle) är en subtyp till en annan typ B (e.g. Polygon), om alla element (värden eller objekt) av typ A (Triangle) kan användas som om de vore av typ B (Polygon). En klasstyp C är en subtyp till: Object Sin superclass (extends) och alla dess supertyper. Alla de interfaces C implementerar (implements). En interfacetyp I är en subtyp till: Object Sitt superinterface (extends) och alla dess supertyper. Vi skriver A <: B för att ange att A är en subtyp till B.

Subtyper och polymorfism Eftersom Triangle <: Polygon, kan en referens till ett objekt av typ Triangle: Tilldelas en variabel med deklarerad typ Polygon. Ges som argument till en metod med parametertyp Polygon. Metoden förväntar sig en Polygon, vilket en Triangle är. Metodens body kan bara bero på gränssnittet för Polygon. Returneras från en metod med deklarerad retur-typ Polygon. Den kod som anropar metoden förväntar sig en Polygon, vilket en Triangle är.

Parameteriserade typer En parameteriserad typ förväntar sig en annan typ som argument för att bli hel. Utan sitt argument har vi en typkonstruktor (type constructor), inte en typ. Vi kan bara skapa objekt av faktiska typer, inte typkonstruktorer. I Java finns: Arrays: [] kan ses som en typkonstruktor för array-typer. Vi har inte en faktisk typ förrän vi anger typen för elementen, e.g. String[]. Generic types: E.g. ArrayList<_> är en typkonstruktor. Vi måste ange en argument-typ för att vi ska ha en faktisk typ, som vi kan skapa objekt av, e.g. ArrayList<String>. (Den icke-parameteriserade versionen ArrayList en bastard, en faktisk typ med implicit argument-typ Object.)

Subtypning för parameteriserade typer Vi vet att subtypning fungerar normalt vad gäller typkonstruktorn: ArrayList<String> <: List<String> <: Object Hur fungerar det för typargumenten? List<Triangle> <: List<Polygon>? Svar: Nej. Varför inte?

Live code

Quiz Arrayer är ett specialfall: Triangle[] <: Polygon[] Vad kan gå fel? Triangle[] triarray = new Triangle[1]; Polygon[] polyarray = triarray; polyarray[0] = new Square(5,10); Triangle t = triarray[0]; Fångas vid runtime: ArrayStoreException

Live code

Variance för parameteriserade typer En typkonstruktors varians (variance) avgör hur subtypning hanteras. Antag att A <: B. Om vi då har: T<A> <: T<B>, då säger vi att T är covariant i sin parameter. Från co- eller com = med, subtypningen varierar med åt samma håll som den för parametern. T<B> <: T<A>, då säger vi att T är contravariant i sin parameter. Från contra = mot, subtypningen varierar emot åt motsatt håll från den för parametern. Inget av ovanstående, då säger vi att T är invariant i sin parameter. Från in- = inte, vi har ingen varierande subtypning alls. Vid flera parametrar kan parametrarna ha olika varians. E.g. T<A,C> <: T<B,D> iff A <: B (covariant) och D <: C (contravariant).

Generiska typer är invarianta Subtypning för argumentet ger ingen subtypning för hela typen: E.g. List<Triangle> <: List<Polygon> gäller inte! Quiz: Varför?

Arrays är covariant Subtypningen varierar med den för argumentet: E.g. eftersom Triangle <: Polygon, så är Triangle[] <: Polygon[] Quiz: Varför, om saker kan gå fel? Svar: För att Java innan Generics behövde den polymorfism det ger.

Live code

Polymorfism för metoder Med generics kan vi ge typ-parametrar inte bara till klasser utan även till metoder: public static <T> T head(t[] a){ return a[0]; } String[] strings = String x = MyClass.<String>head(strings); Kan utelämnas nästan jämt, typcheckaren kommer hitta rätt typ utifrån användandet (typinferens).

Live code

Covariance och collections Vid covariance skulle vi få problem med att lägga till saker i en lista: Om List<Triangle> <: List<Polygon>, då skulle vi tillåta följande: List<Triangle> trilist = new ArrayList<Triangle>(); List<Polygon> polylist = trilist; polylist.add(new Square(5,10)); Att läsa från en lista är däremot inget problem. List<Triangle> trilist = new ArrayList<Triangle>(); List<Polygon> polylist = trilist; Polygon p = polylist.get(0);

Covariance och collections Vid contravariance skulle vi få problem med att läsa saker från en lista: Om List<Polygon> <: List<Triangle>, då skulle vi tillåta följande: List<Polygon> polylist = new ArrayList<Polygon>(); List<Triangle> trilist = polylist; Triangle t = trilist.get(0); Att skriva till en lista är däremot inget problem. List<Polygon> polylist = new ArrayList<Polygon>(); List<Triangle> trilist = polylist; polylist.add(new Square(5,10));

Generics och explicit varians För generiska typer kan vi explicit ange hur vi vill att subtyping ska hanteras: Invariant Covariant Contravariant List<Polygon> inv = new ArrayList<Polygon>(); List<? extends Polygon> cov = new ArrayList<Triangle>(); List<? super Triangle> contv = new ArrayList<Polygon>();? kallas för wildcard.

Existential quantification Notera: List<? extends Polygon> betyder inte att vi har en lista med objekt av olika typer, som var och en är av en subtyp till Polygon. (Det är faktiskt vad vanliga List<Polygon> innebär.) List<? extends Polygon> innebär att referensen pekar på ett objekt av typ List<X>, där allt vi vet om X är att X <: Polygon. (X <: Polygon) sådant att referensen pekar på ett objekt av typen List<X>.

Explicit covariance List<? extends Polygon> cov = Vi kan läsa element ur listan: vad? än representerar, så vet vi att objekten i listan går att betrakta som Polygon. Vi kan inte skriva till listan. Antag att vi vill lägga till en Triangle hur vet vi att det inte faktiskt är en lista av Square? Eller vice versa.

Explicit contravariance List<? super Polygon> cov = Vi kan lägga till element av typen Polygon (eller dess subtyper) till listan. Vad? än representerar vet vi att det är en supertyp till Polygon, vilket innebär att listan kan ta emot objekt av typ Polygon. Vi kan faktiskt läsa från listan men bara som typen Object (eftersom ingenting kan existera som inte är en subtyp till Object).

Funktioner och varians I språk med funktioner (e.g. Haskell) finns polymorfa funktionstyper dessa är också parameteriserade: Typen a -> b har två parametrar, a och b, som ska ges konkreta argument. En funktionstyp a -> b är covariant i b (retur-typ) och contravariant i a (argument-typ). Tänk er att vi förväntar oss en funktion med typ Square -> Polygon. Vi kan använda en funktion Square -> Square eftersom en Square är en Polygon. Vi kan använda en funktion Polygon -> Polygon eftersom en sån funktion kan hantera argument av typ Square. Obs: ovanstående fungerar inte i Haskell eftersom vi inte har (konkreta) subtyper. Motsvarande fungerar dock i t ex OCaml eller C#. I Haskell finns subtyper via classes överkurs.

Contra-contravariance = Covariance En funktion (a -> b) -> c är: Covariant i typen c Contravariant i typen (a -> b) vilket innebär att den är contravariant i b och covariant i a! Testa med konkreta exempel och övertyga er själva.

Metoder och varians Samma princip gäller för metoder, även om vi inte behandlar dem som funktionstyper: En metod som har deklarerad retur-typ Polygon får returnera en Square. En metod som gör @Override på en metod som i superklassen är deklarerad att returnera en Polygon, kan i en subklass deklareras till att returnera e.g. en Square.