Præsentation er lastning. Vent venligst

Præsentation er lastning. Vent venligst

Forelæsning Uge 11 – Torsdag

Lignende præsentationer


Præsentationer af emnet: "Forelæsning Uge 11 – Torsdag"— Præsentationens transcript:

1 Forelæsning Uge 11 – Torsdag
Nedarvning En klasse kan være en subklasse af en anden Det betyder at subklassen arver superklassens feltvariabler og metoder Object klassen Superklasse for alle klasser Indeholder en række nyttige metoder, bl.a. getClass, toString, equals og hashCode Afleveringsopgave: Computerspil 2 Dokumentation og test af de klasser, som I har implementeret i den første delaflevering

2 ● Nedarvning (subklasser)
Vi vil gerne modellere et simpelt nyhedssystem med to slags meddelelser Almindelige tekstmeddelelse (MessagePost) Fotomeddelelse (PhotoPost) Uden brug af nedarvning ser det sådan ud Feltvariabler Metoder Stort overlap, men også forskelle

3 Dublering af kode MessagePost og PhotoPost ligner hinanden
Store dele af de to klassers Java kode er identiske Det gør koden svær at overskue og vanskelig at vedligeholde Der opstår let fejl og inkonsistens, f.eks. når man ændrer noget i den ene klasse, men glemmer at rette i den anden Også dublering i NewsFeed klassen Den har to arraylister Mange metoder gennemløber begge lister (dubleret kode) Det er endnu værre, hvis vi i stedet for to slags postings har mange forskellige slags

4 Forskellige feltvariabler og metoder
Brug af nedarvning (subklasser) Vi kan i stedet lave en Post klasse, som har MessagePost og PhotoPost som subklasser En subklasse arver alle feltvariabler og metoder fra den oprindelig klasse Superklasse Subklasser Bemærk formen på pilehovederne Fælles feltvariabler og metoder Forskellige feltvariabler og metoder Vi har nu kun én arrayliste i NewsFeed klassen postings PhotoPost MessagePost Post Nemmere at overskue Ingen kodedublering

5 Nedarvning i Java public class Post { private String username;
private long timestamp; private int likes; private ArrayList<String> comments; public Post(String author) { username = author; timestamp = System.currentTimeMillis(); likes = 0; comments = new ArrayList<>(); } // Methods omitted Superklasse 4 feltvariabler Konstruktør Initialiserer de 4 feltvariabler Angiver at klassen er en subklasse af Post public class MessagePost extends Post { private String message; public MessagePost(String author, String text) { super(author); message = text; } // Methods omitted Subklasse Feltvariabel I tilgift til de 4, der nedarves Konstruktør Initialiserer feltvariablen Kalder superklassens konstruktør, så de fire nedarvede feltvariabler kan blive initialiseret

6 Access rettigheder public class Post { private String username;
private long timestamp; private int likes; private ArrayList<String> comments; public Post(String author) { username = author; timestamp = System.currentTimeMillis(); likes = 0; comments = new ArrayList<>(); } // Methods omitted Superklasse De 4 feltvariabler i superklassen er private Subklassen kan (som alle andre klasser) kun tilgå dem via public accessor og mutator metoder defineret i superklassen public metoder fra superklassen kan kaldes i subklassen som om de var lokale Uden brug af dot notation methodName(args) public class MessagePost extends Post { private String message; public MessagePost(String author, String text) { super(author); message = text; } // Methods omitted Subklasse Java kræver at første sætning i en subklasses konstruktør er et kald til superklassens konstruktør Hvis dette ikke er tilfældet, indsætter compileren et sådant kald (uden parametre)

7 Subtyper Alle objekt klasser bestemmer en type
Når en klasse B er en subklasse af klassen A, siger vi at typen B er en subtype af typen A (som er en supertype af typen B) De steder, hvor der skal bruges et objekt af typen A, kan man i stedet bruge et objekt af en subtype B Assignments Parameterværdier Returværdier Elementer i objektsamlinger A a; B b; a = b; public void pip(A param) {...}; public A pop() { ... return b; } pip(b); Ovenstående er kendt som Liskovs substitutionsprincip Vi har tidligere sagt at typerne skal matche (for assignments, parametre og returværdier) ArrayList<A> list; B b; list.add(b); Mere præcist betyder det, at typen af udtrykket skal være den samme som variablens/parameterens type eller være en subtype heraf

8 NewsFeed klassen public class NewsFeed {
private ArrayList<Post> posts; public NewsFeed() { posts = new ArrayList<>(); } public void addPost(Post post) { posts.add(post); public void show() { for(Post post : posts) { post.display(); System.out.println(); Feltvariabel Arrayliste med elementtypen Post Elementerne i listen vil være af typen MessagePost eller PhotoPost Konstruktør Initialiserer feltvariablen Metode til indsættelse af postings Bemærk at parameteren er af typen Post Argumenter af typen MessagePost og PhotoPost er også lovlige Metode til udskrift af alle postings For-each løkken løber arraylisten igennem og udskriver de enkelte elementer ved hjælp af display metoden fra Post klassen

9 Statisk og dynamisk type
Lad os se lidt nærmere på show metoden fra foregående slide public void show() { for(Post post : posts) { post.display(); System.out.println(); } Den lokale variabel post er erklæret til at have typen Post Vi siger derfor, at den statiske type for variablen post er Post De objekter som variablen post vil pege på er af typen MessagePost eller typen PhotoPost Vi siger derfor, at den dynamiske type for post er MessagePost, når post peger på et MessagePost objekt PhotoPost, når post peger på et PhotoPost objekt Opsummering Den statiske type bestemmes af variablens erklæring Den dynamiske type bestemmes af det objekt, som variablen pt peger på

10 Typeskift (type cast) Vehicle v1 = new Vehicle();
Vehicle v2 = new Car(); Vehicle v3 = new Bicycle(); Vehicle v = new Car(); Car c = new Car(); v = c; // Lovligt c = v; // Ulovligt, compile-time fejl Javas variabler er polymorfe De kan antage værdier af forskellig type Polymorf ≈ kan antage forskellige former c = (Car) v; // Lovligt Type cast Typen af udtrykket ændres til at være Car Kun muligt, hvis den dynamiske type af v er Car (eller en subtype af Car) Ellers får man en run-time fejl Objektet v ændres ikke på nogen måde ved et type cast Det eneste, der ændres, er typen af udtrykket på højresiden af assignmentet

11 Nedarvning i flere niveauer
En subklasse kan igen have subklasser, osv. Dog klassen er en Direkte subklasse af Mammal klassen Subklasse af Animal klassen (subklasse relationen er transitiv) Subklasse af sig selv (subklasse relationen er refleksiv) Direkte superklasse for Poodle og Dalmatian klasserne Superklasse af sig selv (superklasse relationen er refleksiv og transitiv)

12 Klassediagram for brug af Comparator
Collections T min(Collection<T> c) T max(Collection<T> c) void sort(List<T> l) ... <<interface>> Comparable int compareTo(T o) <<interface>> Collection boolean add(E e) boolean contains(Object o) ... 3 forskellige slags UML pile Fuldt optrukne pile med lukket hoved angiver nedarvning mellem klasser/interfaces Stiplede pile med lukket hoved angiver implementation af interface Stiplede pile med åbent hoved angiver brug (uses) <<interface>> List <<interface>> Queue <<interface>> Set Pixel Person String ArrayList LinkedList HashSet Adult Child

13 Forskellige feltvariabler og metoder
● Metoder i subklasser Lad os nu kigge lidt nærmere på metoder i super- og subklasser Post klassen har en display metode, der udskriver information om klassens tilstand display metoden har kun adgang til feltvariabler i Post klassen Hvad gør vi, hvis vi gerne vil udskrive information om subklassernes feltvariabler? Fælles feltvariabler og metoder Forskellige feltvariabler og metoder Sidebemærkning (om cohesion) display metoden udskriver klassens tilstand Det ville være bedre at have en toString metode, der returnerer en tekststreng Så kan man på kaldstedet selv bestemme, hvad man vil gøre ved tekststrengen

14 Situationen er som vist nedenfor
public void display() { System.out.println( username ); System.out.print(timeString( timestamp )); if( likes > 0) { System.out.println(likes + " people like this."); } else { System.out.println(); if( comments .isEmpty()) { System.out.println("No comments."); System.out.println(comments.size() + " comment(s)."); Post public void show() { for(Post post : posts) { post.display (); System.out.println(); } Post klassens display metode kender ikke de feltvariabler, der ligger i subklasserne, og kan derfor ikke udskrive information om disse Newsfeed

15 Første løsningsforslag (virker ikke)
Vi kan flytte display metoden til de to subklasser Det giver massiv kodedublering Metoderne har kun adgang til superklassens feltvariabler via acces metoder Vi får en compile-time fejl i NewsFeed klassen xxx Den lokale variabel post har Post som sin statiske type public void show() { for( Post post : posts) { post.display (); System.out.println(); } Newsfeed Oversætteren bruger altid den statiske type og kigger derfor (uden held) i Post klassen (og dens superklasser) for at finde display metoden Det hjælper ikke, at alle subklasserne har en display metode

16 Korrekt løsning Vi har både en display metode i superklassen og i de to subklasser Vi undgår kodedublering display metoderne i subklasserne kalder (via super) display metoden i superklassen og har (via den) adgang til superklassens feltvariabler uden brug af acces metoder public void display() { super.display(); System.out.println(message); } MessagePost public void display() { super.display(); System.out.println(filename); System.out.println(caption); } PhotoPost

17 Statiske type Oversætteren bruger den statiske type, dvs. typen fra variablens erklæring Den lokale variabel post er erklæret til at være af typen Post Oversætteren kigger derfor i Post klassen for at finde display metoden (og finder den) public void show() { for( Post post : posts) { post.display (); System.out.println(); } Newsfeed

18 Dynamiske type Under programudførelsen bruges den dynamiske type, dvs. typen af variablens aktuelle værdi Når den aktuelle værdi af post er en MessagePost kaldes displaymetoden fra MessagePost Når den aktuelle værdi af post er en PhotoPost kaldes display metoden fra PhotoPost public void show() { for(Post post : posts) { post.display (); System.out.println(); } Newsfeed De to subklasser overskriver superklassens display metode med deres egne udgaver af metoden På engelsk: override ≈ underkende/tilsidesætte De nye metoder skal have samme signatur som den de overskriver Når man overskriver en metode, bør man (af hensyn til compileren/ dem der læser koden) i linjen over metodesignaturen Pause

19 Simpelt eksempel (kun en klasse)
Ingen nedarvning Ingen overskrivning v1.display(); Vi bestemmer v1’s dynamiske type Find variablen v1 Find det objekt, som v1 peger på Find objektets type (klasse) display metoden søges i PhotoPost og findes der

20 Nedarvning uden overskrivning
v1.display(); Vi bestemmer v1’s dynamiske type Find variablen v1 Find det objekt, som v1 peger på Find objektets type (klasse) display metoden søges i PhotoPost (uden held) display metoden søges i superklasserne (efter tur) og findes i Post display findes altid ellers ville vi have fået en compile-time fejl

21 Nedarvning med overskrivning
display v1.display(); Vi bestemmer v1’s dynamiske type Find variablen v1 Find det objekt, som v1 peger på Find objektets type (klasse) display metoden søges i PhotoPost og findes der

22 Dynamic method lookup (opsummering)
Under udførslen findes den rigtige metoden ved at bestemme variablens dynamiske type søge metoden i denne klasse eller i en superklasse af den Oversætteren har tjekket, at metoden findes i variablens statiske type (eller en af dennes superklasser) Den dynamiske type er en subtype af den statiske type Vi er derfor sikre på at finde metoden Den er i den statiske type (eller en af dennes superklasser), men kan være overskrevet i en subtype af den statiske type Ovenstående er kendt som dynamic method lookup Spiller en essentiel rolle i anvendelsen af subklasser Tillader at de enkelte subklasser kan lave deres egne specialtilpassede versioner af en metode Eksempel på responsibility-driven design

23 Polymorfi Betyder at noget kan antage forskellige former
Vi har tidligere set, at Javas variabler er polymorfe De kan antage værdier af forskellig type Vi har nu set, at også Javas metoder er polymorfe Et metodekald kan aktivere metoder i forskellige klasser (typer) public void show() { for(Post post : posts) { post.display (); System.out.println(); } Metodekaldet aktiverer sommetider display metoden i MessagePost og sommetider display metoden i PhotoPost Newsfeed

24 ● Object klassen Alle klasser i Java er subklasser af Object klassen
Object klassen indeholder en række nyttige metoder, som de øvrige klasser nedarver (eller overskriver) getClass metoden fortæller, hvilken klasse objektet tilhører toString metoden returnerer en tekstrepræsentation af det pågældende objekt equals metoden tjekker om to objekter "ligner hinanden" hashCode metoden beregner en hashkode

25 getClass metoden og instanceof
Man kan undersøge et objekts klasse på forskellige vis Ved hjælp af det reserverede ord instanceof Her testes om objektet tilhører den angivne klasse eller en subklasse heraf Vehicle v; Car c; if( v instanceof Car ) { c = (Car) v; } Ved hjælp af getClass metoden (fra Object klassen) Metoden returnerer et objekt fra klassen Class I et kørende program har hver type (også de primitive) et (og kun et) tilhørende objekt i Class Class er en parametriseret type og objektet for klassen A tilhører Class<A> if( x.getClass() = = y.getClass() ) {...} Man kan også skrive som vist nedenfor (hvor Person.class angiver Person klassens objekt i klassen Class<Person>) if( x.getClass() = = Person.class ) {...} I de to sidste tilfælde skal klasserne matche eksakt – det er ikke nok at den ene er en subklasse af den anden (som ved brug af instanceof)

26 toString metoden Metoden bruges bl.a. i print og prinln metoderne
Hvis argumentet til metoderne ikke allerede er en tekststreng, bruges toString til at konvertere argumentet til en tekststreng Det er også toString metoden, der bruges, når den ene side af en + operation skal konverteres til en tekststreng I Object klassen er toString metoden defineret til at returnere hvor Person er klassens navn og 19bb25a er den hexadecimale repræsentation af hashkoden (som vi vender tilbage til) Hashkoden giver ikke ret meget interessant information String klassen redefinerer metoden til at returnere værdien af tekststrengen (i stedet for Jeres egne klasser bør også redefinere toString metoden For personklassen kan man f.eks. returnere tekststrengen Cecilie:18, hvor Cecilie er personens navn og 18 er personens alder I køreprøveopgaverne blev I altid bedt om at redefinere toString metoden (for den simple af klasserne)

27 equals metoden Metoden bruges bl.a. i collections til at afgøre om et givet element er indeholdt i en mængde (Set) for en mængde vil et kald add(elem) kun tilføje elementet, hvis der ikke eksisterer et element e i mængden, så elem.equals(e) er sand I Object klassen er equals metoden defineret ved hjælp af == Det betyder at e1.equals(e2) kun evaluerer til sand, hvis de to objekter er identiske (e1 == e2) Dette er ofte for restriktivt String klassen redefinerer metoden til at tjekke om de to tekststrenge er ens, dvs. indeholder de samme tegn (i samme rækkefølge) Jeres egne klasser bør også redefinere equals metoden Det kræves at equals er en ækvivalensrelation Refleksiv: x.equals(x) for alle x Symmetrisk: x.equals(y)  y.equals(x) for alle x,y Transitiv: x.equals(y)  y.equals(z)  x.equals(z) for alle x,y,z Teknisk: x != null  !x.equals(null) for all x

28 Redefinering af equals metoden
For Person klassen kan man definere equals som følger public boolean equals(Object otherObject) { if( this = = otherObject ) {return true;} if( otherObject = = null ) {return false;} if( getClass() != otherObject.getClass() ) {return false;} Person other = (Person) otherObject; return name.equals(other.name) && age == other.age; } Optimalisering null? Rigtig klasse? Type cast Sammenlign (udvalgte) feltvariabler I subklassen Child kan man definere equals som følger public class Child extends Person { private int noOfToys; ... public boolean equals(otherObject) { if( !super.equals(otherObject) ) {return false;} return noOfToys = = other.noOfToys; } Kald af equals i superklassen korrekt klasse mv superklassens feltvariabler Feltvariabel Tjek af egne feltvariabler

29 hashCode metoden Metoden returnerer en hashkode for objektet
Hashkoder bruges som nøgler i såkaldte hashtabeller, f.eks. i klasserne HashSet og HashMap Det kræves, at hashcode er konsistent med equals x.equals(y)  hashcode(x) == hashCode(y) Derudover bør hashCode være konstrueret således, at der for to forskellige objekter (! x.equals(y)) er lille sandsynlighed for at deres hashkoder kolliderer (hasCode(x) == hashCode(y)) I Object klassen er hashCode metoden defineret som objektets memory adresse Dermed er det nemt at se, at hashCode er konsistent med equals Hvis jeres egne klasser redefinerer equals metoden, vil det normalt også være nødvendigt at redefinere hashCode metoden Dette gøres for at sikre at ovenstående betingelse stadig er opfyldt

30 Hashkoder for tekststrenge
Det er en hel videnskab at definere hashkoder, hvor der er så få kollisioner som muligt Lad os starte med at se, hvordan hashCode kan defineres i String klassen s er en feltvariabel, der indeholder værdien af tekststrengen public int hashCode() { int hc = 0; for( int i = 0; i < s.length(); i++) { hc = hc + s.charAt(i); } return hc; hc = 31 * hc + s.charAt(i); hashCode("eat") = 312 * 'e' + 31 * 'a' + 't' = hashCode("eat") = 'e' + 'a' + 't' = = 314 hashCode("tea") = 312 * 't' + 31 * 'e' + 'a' = hashCode("tea") = 't' + 'e' + 'a' = = 314

31 Hashkoder for jeres egne klasser
For Person klassen kan man definere hashCode som følger Vi bruger kun de feltvariabler, som tjekkes i equals metoden Primitive værdier konverteres først til deres wrapper type Hashkoderne multipliceres med forskellige primtal før de adderes public int hashCode() { return 11 * name.hashCode() + 13 * new Integer(age).hashCode(); } I subklassen Child kan man definere hashCode som følger public class Child extends Person { private int noOfToys; ... public boolean hashCode() { return super.hashCode() + 17 * new Integer(noOfToys).hashCode(); } Feltvariabel Hashkode for superklassens feltvariabler Hashkode for egne feltvariabler

32 ● Afleveringsopgave: Computerspil 2
I den anden delaflevering skal I bruge nogle af de ting, som I har lært om dokumentation og test, på de fire klasser, som I har implementeret i den første delaflevering Gennemgå de fire klasser, og tilføj dokumentation, således at den er helt i top og følger de retningslinjer, der gives i BlueJ bogen (herunder specielt afsnit 6.11, afsnit 9.7 og Appendix I) Lav velvalgte regression tests for de fire klasser I skal både teste, hvad der normalt sker, og hvad der sker i specialtilfælde og tæt ved grænseværdier Husk, at der skal være både positive og negative tests Det er dog ikke nødvendigt at lave test metoder for trivielle accessor og mutator metoder, der blot returnerer/ændrer en enkelt feltvariabel uden at gøre andet Herudover skal I rette de fejl og mangler, som instruktoren har påpeget i jeres første delaflevering

33 Dokumentation af Road klassen
/** * Represents a road (between to cities). * A road is one-directional. This means that we may have a road from * City A to City B, without having a road from City B to City A. * Kurt Jensen. April 2017. */ public class Road implements Comparable<Road> { /** References to the cities connected by this Road */ private City from, to; /** Length of this Road. */ private int length; * Creates a new Road object. from City where this Road starts. to City where this Road ens. length Length of this Road object. public Road(City from, City to, int length){ this.from = from; this.to = to; this.length = length; } * Returns a reference to the City where this Road starts. from city. public City getFrom(){ return from; ... Kommentar for klassen Kommentar for feltvariablerne Kommentar for konstruktøren Kommentar for metoden

34 Documentation view Husk at kontrollere, at resultatet er fornuftigt
Skal give relevant og letlæselig information Til brugere, der ikke kender implementationen af jeres klasser.

35 Test of Road klassen import static org.junit.Assert.*;
import org.junit.After; import org.junit.Before; import org.junit.Test; public class RoadTest { private Country country1, country2; private City cityA, cityB, cityC; @Before public void setUp() { country1 = new Country("Country 1", null); cityA = new City("City A", 80, country1); cityB = ... cityC = ... } ... Fra den generelle Test Fixture kan I "stjæle" import sætningerne Feltvariablerne for landet og byerne Erklæringerne i setUp metoden (idet vi dog sætter netværket til null, da vi ikke skal bruge det) For overskuelighedens skyld bør I fjerne de dele, som I ikke bruger I skal lave en test metode for hver (ikke triviel) konstruktør/metode Hver testmetode tester flere forskellige ting (via forskellige assertions) @Test public void constructor() { Road road = new Road(cityA, cityB, 4); assertEquals(road.getFrom(), cityA); ... } Testmetode for konstruktøren Vi skaber et Road objekt og tjekker at feltvariablerne initialiseres korrekt Testmetode for compareTo Vi skaber veje mellem byerne fra vores Test Fxiture (setUp metode) og tjekker at compareTo returnerer værdier med korrekt fortegn @Test public void compareTo() { Road road1 = new Road(cityA, cityB, 0); Road road2 = new Road(cityA, cityC, 0); Road road3 = new Road(cityB, cityA, 0); assertTrue(road1.compareTo(road2) < 0); ... assertTrue(road2.compareTo(road1) > 0); assertEquals(road1.compareTo(road1), 0); } Test All:

36 Test af Position import ... public class PositionTest {
private Country country1; private City cityA, cityB; private Position pos; @Before public void setUp() { country1 = new Country("Country 1", null); cityA = ... cityB = ... pos = new Position(cityA, cityB, 3); } Disse ting kan I (som før) stjæle fra den generelle Test Fixture Sætningerne i de to to grønne bokse skal I selv tilføje Som før skal I lave en test metode for hver (ikke triviel) konstruktør/metode Hver testmetode tester flere forskellige ting (via forskellige assertions) @Test public void constructor() { assertEquals(pos.getFrom(), cityA); ... } Testmetode for konstruktøren Vi tjekker at feltvariablerne initialiseres korrekt Testmetode for hasArrived metoden Hvor mange gange skal move metoden kaldes før hasArrived returnerer true? @Test public void hasArrived() { assertFalse(pos.hasArrived()); pos.move(); ... assertTrue(pos.hasArrived()); } Når man har lavet et par optagelser af test metoder og set, hvordan de ser ud, er det langt hurtigere at skrive test metoderne selv

37 Test af Position klassen (fortsat)
Testmetode for move Kald move metoden et antal gange og test hver gang værdierne af distance og returværdi @Test public void move() { assertEquals(pos.getDistance(), 3); assertTrue(pos.move()); assertEquals(pos.getDistance(), 2; ... } Testmetode for turnAround move + turnAround turnAround Efter hvert kald af turnAround tjekkes, at feltvariablerne i pos har de korrekte værdier @Test public void turnAround() { pos.move(); pos.turnAround(); assertEquals(pos.getFrom(), cityB); ... assertEquals(pos.getFrom() == ... ...; } A Hvis man højreklikker testklassen og vælger Test All får man B C

38 Assertions Som I har set, kan assertions skrives på flere forskellige måder assertEquals, assertTrue, eller assertFalse Det er lige meget hvilken af de tre assert metoder, man bruger assertEquals bruger (som navnet antyder) equals metoden til at sammenligne de to værdier (af en Objekt type) Disse tre sætninger er ækvivalente assertEquals(false, pos.hasArrived()); assertTrue(!pos.hasArrived()); assertFalse(pos.hasArrived()); Disse to sætninger er ækvivalente assertEquals(cityA, pos.getFrom()); assertTrue(cityA.equals(pos.getFrom())); Bemærk at knappen Run Tests kun tester metoderne i de test klasser, der allerede er succesfuldt kompileret

39 Eksempler på testmetoder for Country
public void reset() { cityA.arrive(null); cityA.arrive(null); cityA.arrive(null); cityE.arrive(null); cityE.arrive(null); cityE.arrive(null); int valueE = cityE.getValue(); // Remember value of City E country1.reset(); assertEquals(cityA.getValue(), 80); // City A is reset assertEquals(cityE.getValue(), valueE); // City E is not reset } arrive kaldes 3 gange Så er man nogenlunde sikker på at byens værdi er ændret @Test public void bonus() { for(int seed = 0; seed < 1000; seed++) { // Try 1000 different seeds game.getRandom().setSeed(seed); int sum = 0; Set<Integer> values = new HashSet<>(); for(int i = 0; i < 10000; i++) { // Call method times int bonus = country1.bonus(80); sum += bonus; values.add(bonus); } assertTrue(... < sum && sum < ...); // Average close to 40 assertEquals(values.size(), ...); // All values returned Man bør lave tilsvarende tests for grænsetilfældene, hvor bonus kaldes med parametrene 0 og 1

40 Test af metoder med tilfældige værdier
Når man skal teste arrive metoden i City klassen kan det være nyttigt at resette den seed værdi som Random objektet bruger På den måde kan man finde ud af hvad bonus metoden returnerer, når den kaldes inde fra arrive @Test public void arrive(){ int bonus = country1.bonus(80); // Remember bonus game.getRandom().setSeed(0); // Reset seed int arrive = cityA.arrive(); // Same bonus assertEquals(arrive, ...); assertEquals(cityA.getValue(), ...); } Test at returværdi og værdien af value er korrekt Man kan også proppe det hele ind i en for løkke og dermed teste mange forskellige seed værdier Tager ikke meget længere tid Det er opsætningen af Test Fxituren, der er dyr @Test public void arrive(){ for(int i=0; i<1000; i++) { // Try different seeds game.getRandom().setSeed(i); // Set seed int bonus = country1.bonus(80); // Remember bonus game.getRandom().setSeed(i); // Reset seed int arrive = cityA.arrive(); // Same bonus as before assertEquals(arrive, ...); assertEquals(cityA.getValue(), ...); cityA.reset(); } Husk at resette byen mellem de enkelte tests

41 ● Opsummering Nedarvning Metoder i subklasser Object klassen
Forskellen på en variabels statiske og dynamiske type Subtyper og Liskovs substitutionsprincip Typeskift (type cast) Metoder i subklasser Dynamic method lookup i forbindelse med nedarvning og overskrivning Object klassen Superklasse for alle klasser Indeholder en række nyttige metoder, bl.a. getClass, toString, equals og hashCode Afleveringsopgave: Computerspil 2 Dokumentation og test af de klasser, som I har implementeret i den første delaflevering

42 Det var alt for nu….. … spørgsmål


Download ppt "Forelæsning Uge 11 – Torsdag"

Lignende præsentationer


Annoncer fra Google