Föreläsnings 10 - Överlagring, Konstruerare, Arv, Mer Exceptions, Reguljära Uttryck Josef Svenningsson Tisdag 13/1
Överlagring Ur klassen Math: public static max(int a, int b) public static max(double a, double b) Ur klassen String: public String substring(int beginindex) public String substring(int beginindex, int endindex) Regel: Två metoder i samma klass få ha samma namn om parametrarna skiljer sig åt i antal och/eller typ.
Överlagring av Konstruerare Ur klassen Scanner public Scanner(String source) public Scanner(File file) public Scanner(Readable source) Regel: En klass får ha flera konstruerare om parametrarna skiljer sig åt i antal och/eller typer. Om man inte definierar någon konstruerare definieras implicit en utan parametrar som inte gör någonting. Konstrueraren utan argument (om en sådan finns) kallas standardkonstrueraren
Överlagring Använd överlagring försiktigt. Om två metoder heter samma sak så är det viktigt att de gör ungefär samma sak. Annars blir det väldigt förvirrande att använda dem.
Uppvärmning: punkter i planet public class Point2 { private int x, y; public Point2(int x, int y) { this.x = x; this.y = y; public void move(int dx, int dy) { x += dx; y += dy; public double distancetoorigin() { return Math.sqrt(x*x + y*y);
En subklass: punkter i rummet public class Point3 extends Point2 { private int z; public Point3(int x, int y, int z) { super(x,y); this.z = z; public void move(int dx, int dy, int dz) { move(dx,dy); z += dz; public double distancetoorigin() { double d = super.distancetoorigin(); return Math.sqrt(d*d + z*z);
Kommentarer till Point2 och Point3 Point3 är en subklass till Point2 Point2 är en superklass till Point3 Point3 ärver från Point2 I en subklass kan man Lägga till instansvariabler Lägga till kontruerare och metoder Omdefiniera superklassens metoder p = new Point2(3,4) p har instansvariabler x och y p erbjuder metoderna p.move(dx,dy) p.distancetoorigin() p = new Point3(3,4,12) p har instansvariabler x, y och z p erbjuder metoderna p.move(dx,dy) p.distancetoorigin() p.move(dx,dy,dz)
Subtypning En instans av Point3 erbjuder alla metoder som objekt av supertypen Point2 erbjuder. Slutsats: En instans av Point3 har också typen Point2. Det är korrekt att deklarera Point2 p = new Point3(2, 3, 12); Vi säger att Point3 är en subtyp till Point2. Vad händer med följande exempel? public class Main { public static void main(string[] args) { Point2 p = new Point3(2, 3, 12); p.move(1,1); p.move(1,1,1); System.out.println(p.distanceToOrigin());
Svar på vad som händer p.move(1,1) Metoden move i Point2 exekveras; p får de nya koordinaterna x=3, y=4 och behåller z=12 p.move(1,1,1) Detta är typfel! Vi har deklarerat variabeln p att ha typen Point2, som inte erbjuder någon move med tre argument. p.distancetoorigin() Objektet avgör vilken metod som exekveras. Objektet är en instans av klassen Point3, så den omdefinierade metoden i Point3 exekveras och resultatet 13.0 skrivs ut.
Konstruerare och metoder i subklasser Konstruerare Normalt börjar subklassens konstruerare med att anropa en konstruerare i superklassen: Point3(int x, int y, int z) { super(x,y);... Om man inte skriver ett sådant anrop först lägger kompilatorn in ett anrop av superklassens standardkonstruerare. Finns ingen sådan fås kompileringsfel. Omdefinierade Metoder När en metod omdefinieras behöver man ofta använda superklassens metod; detta åstadkommes med super. som prefix till anropet.
Synlighet för instansvariabler private Instansvariabler som är private är inte synliga i subklasser. I subklassen kan vi bara använda de publika metoder som superklassen tillhandhåller. protected Om instansvariablerna i stället är protected så är de synliga i subklasser. Exempel Om x och y i Point2 vore protected, så skulle distancetoorigin i Point3 kunna skrivas: return Math.sqrt(x*x + y*y + z*z);
Arv I Javas standardbibliotek så används arv mellan klasser väldigt flitigt. Det ger upphov till återanvändning av kod och fungerar bra för att strukturera bibliotek. Dock är det så att Ofta när man skriver egna program så tenderar man till att använda arv relativt lite. Ansträng er inte i onödan för att använda arv.
Klasshierarki Delar av klasshierarkin för grafikpaketet i Java.
Klassen Object En klass som inte explicit anges som subklass (extends... ) blir automatiskt en subklass till klassen Object. Denna klass erbjuder bland annat metoderna public boolean equals(object obj) String tostring() som alltså är definierade för alla objekt. Också fält, som inte är subtyper av någon klass, erbjuder dessa metoder.
Subklasser och interface En viktig skillnad mellan subklasser och interface är följande: En subklass kan återanvända metoder och instansvariabler från superklassen den ärver ifrån. Interface kan bara garantera att klasser implementerar vissa metoder.
Subklasser och interface Regler En klass kan bara vara subklass till en annan klass, men kan implementera många interfaces. Interfaces leder också till subtypning: om C implements I, så är C en subtyp till I. Att använda interfaces och definiera klasser som implementerar dessa är ofta att föredra framför att definiera klasshierarkier. Ett mellanting som kan erbjuda fördelar är abstrakta klasser.
Abstrakta klasser En abstrakt klass: är en klass där en eller flera metoder är abstrakta, dvs endast deras signatur ges. måste i huvudet deklareras som sådan, t ex public abstract class Shape har inga konstruerare; man kan inte skapa objekt av klassen. är avsedd att kombineras med subklasser som deklarerar de abstrakta metoderna. I denna kurs kommer vi i stort sett att ignorera abstrakta klasser.
Mer Exceptions Betrakta följande try - catch sats: try {... catch (FileNotFoundException e) {... Denna fångar alla exceptions av typ FileNotFoundException och alla exceptions som är subklasser av denna klass.
Klassen Exception Det finns en superklass till alla exceptions, och den heter Exception. Om man vill fånga alla exceptions i ett try - catch block så kan man skriva på följande sätt. try {... catch (Exception e) {... Detta är dock inte att rekommendera, var noga med vilka exceptions ni fångar.
Klasshierarkin för Exceptions i Java Exceptions som är subklasser av RuntimeException är unchecked. Alla andra som är subklasser av Exception är checked.
Kasta mer Excpetions När man kastar vidare exceptions så går det bra att deklarera en superklass till de exceptions som man kan kasta. Om man vill vara lat public void method(string s) throws Exception Man ska dock alltid se till att skriva så specifika exceptions som möjligt, detta är mer användbart för den som sedan anropar koden och behöver fånga ett exception.
Skapa egna exceptions Det är lätt att skapa en egen form av exception i Java. Det enda man behöver göra är att skapa en ny klass och ärva från Exception. public class AjaBaja extends Exception { public String tostring() { return "Aja baja, så får du inte göra!";
Skapa egna exceptions Metoden tostring() i ett exception används när vårt exception skrivs ut om programmet kraschar på grund av att det inte fångats. public class ThrowAjaBaja { public static void main(string[] args) throws AjaBaja { throw new AjaBaja(); Ovanstående program ger följande utskrift: Exception in thread "main" Aja baja, så får du inte göra! at ThrowAjaBaja.main(ThrowAjaBaja.java:4)
Mer om klassen Scanner Klassen Scanner innehåller metoden String findinline(string pattern) som försöker hitta en sträng som matchar pattern på den aktuella raden. Misslyckas detta returneras null och aktuell position är oförändrad. Matchningen utnyttjar reguljära uttryck. Reguljära uttryck utnyttjas i många sammanhang för sökning.
Reguljära uttryck Ett reguljärt uttryck är en sträng där vissa tecken (metatecken) har särskild betydelse. Metatecken är. + *? [ ] ^ \. Här är några exempel på när ett reguljärt uttryck matchar en sträng. a[dg]a matchar ada och aga. a[d-g]a matchar ada, aea, afa och aga. a[1-4] matchar a1, a2, a3 och a4. ab+a matchar aba, abba, abbba... ab*a matchar samma strängar och också aa. [0-9]+ matchar alla icke-tomma strängar med bara siffror. a.a matchar aaa, aba, aca... a\\.a matchar a.a
Reguljära uttryck i jgrasp jgrasp har en väldigt trevlig funktionalitet för att experimentera med reguljära uttryck. Gå till menyn och klicka på Tools > Regular Expression Tester.