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

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

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

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

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

Kopiering av objekt i Java

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

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

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

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

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

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

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

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

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

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

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

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

Generisk klass med typparameter Inre klass - ListIterator

DAT043 - Föreläsning 7

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

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

Objektorienterad programmering med Java, Generics

Generiska konstruktioner. Kursbokens kapitel 13

Arrayer. results

OOP Objekt-orienterad programmering

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

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

Typecasting - primitiva typer. Innehåll. DoME klasser

Modeller, Objekt och Klasser

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

OOP Objekt-orienterad programmering

Java, klasser, objekt (Skansholm: Kapitel 2)

Föreläsning 4. Klass. Klassdeklaration. Klasser Och Objekt

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

Föreläsning 5 (6) Metoder. Metoder Deklarera. Metoder. Parametrar Returvärden Överlagring Konstruktorer Statiska metoder tostring() metoden javadoc

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

Instuderingsuppgifter läsvecka 6 - LÖSNINGAR

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

Lösningar för tenta 3 DAT043,

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

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

Sammansatta datatyper Generics: Parametrisk polymorfism

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

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

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

Objektorienterad Programmering (TDDC77)

Objektorienterad Programmering DAT043

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

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

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

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

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

Laboration 1 - Grunderna för OOP i Java

Samlingar, Gränssitt och Programkonstruktion! Förelasning 11!! TDA540 Objektorienterad Programmering!

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

Länkade strukturer, parametriserade typer och undantag

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

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

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

Polymorfi. Objektorienterad och komponentbaserad programmering

TDDD78 Viktiga begrepp, del 2

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

Laboration A Objektsamlingar

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

OOP Objekt-orienterad programmering

OOP Objekt-orienterad programmering

Föreläsningsmaterial (Arv) Skrivet av Andreas Lund

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

Sammansatta datatyper Generics: Parametrisk polymorfism

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

Arv Murach s: kap 14

Arv. Objektorienterad och komponentbaserad programmering

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

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

Objektorienterad Programmering (TDDC77)

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

Uno Holmer, Chalmers, :17 Uno Holmer, Chalmers, :17

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

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

Föreläsning 13 Innehåll

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

Dynamisk bindning och polymorfism

DAT043 Objektorienterad Programmering

Laboration 1: Figurer i hierarki

TDDD78 Objektorientering i Java, del 2

Generiska klasser och funktioner

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

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

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

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

Konstruktion av klasser med klasser

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

Transkript:

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

Idag pratar vi om statiska typer...om inte annat anges.

Subtypsrelationen A <: B A är en subtyp till B Triangle <: Polygon Ett objekt av typ Triangle kan användas som om det hade typ Polygon

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.) Jämför med Haskell: [] och Maybe är typkonstruktorer, [String] och Maybe Bool är typer.

Subtypning och parameterisering 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?

Variance för parameteriserade typer En typkonstruktors varians (variance) avgör hur subtypning hanteras. Covariance: om A <: B så T<A> <: T<B> Contravariance: om A <: B så T<B> <: T<A> Invariance: T<A> <: T<A>

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

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<Object>();? kallas för wildcard eller unknown.

Generics och explicit varians List<Polygon> Varje element i listan är en Polygon List<? extends Polygon> Varje element i listan är en X, för något X sådant att X <: Polygon List<? super Triangle> Varje element i listan är en X, för något X sådant att Triangle <: X

Live fruktstund

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 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);

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 lägga objekt i 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. (Vi kan lägga till null, eftersom alla objekttyper är nullable.)

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).

Get-put principle När du hämtar objekt ur en struktur, använd covariance. När du placerar objekt i en struktur, använd contravariance. När du gör bådadera, använd invariance. Kod som följer get-put-principen är mer återanvändbar!

Live code

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>.

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

Arrays är covariant Till exempel, Triangle[] <: Polygon[] Vi får göra både get och put (på egen risk!) Triangle[] triarray = new Triangle[1]; Polygon[] polyarray = triarray; polyarray[0] = new Square(5,10); Triangle t = triarray[0]; Fångas vid runtime: ArrayStoreException Varför, om saker kan gå fel? För att Java innan Generics behövde den polymorfism det ger.

Live code

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. Covariant overriding i returtypen: en metod som gör @Override kan t ex returnera en Square om motsvarande metod i superklassen returnerar Polygon. Contravariant overriding i argumenttypen är inte möjligt i Java (tolkas som overloading).