TDDC30 Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Jonas Lindgren, Institutionen för Datavetenskap, LiU På denna föreläsning: Interface Generiska klasser Undantag 1 Gränssnitt Återbesök hos ordboken public abstract class Dictionary{ public abstract bool lookup(string key); Hmm, en klass helt utan implementerade metoder blir ju bara ett gränssnitt. Finns det inte något elegantare sätt att visa det? JAJAMEN! 2 1
Gränssnitt(2) Interface och arv, jämförelse public abstract class Dictionary{ public abstract bool lookup(string key); public class MyDictionaryImpl extends Dictionary{... public interface Dictionary{ public bool lookup(string key); public class MyDictionaryImpl implements Dictionary{... 3 Gränssnitt(3) God programmeringssed Ett interface är att betrakta som ett kontrakt mellan implementeraren och användaren Interfacet lovar att för evigt supporta dess metoder och aldrig ändra sig Men jag vill förbättra mitt program, ju Lösning: Skapa ett nytt interface som ärver från det gamla Bryt inte kontraktet! 4 2
Gränssnitt(4) Definition: Interface är en referenstyp, precis som klass, som endast kan innehålla konstanter och metoddeklarationer (och nästlade typer) Egenskaper för interfaces Samtliga metoder är per automatik public abstract -> Programmeraren slipper skriva detta -> Går ej att definiera som protected eller private Samtliga konstanter är per automatik public final En klass som implementerar ett interface måste implementera alla dess metoder. 5 Gränssnitt(5) Exempel: public interface Eatable{ int BEINGEATENCOLOR = 0xFF3333; void eat(); public abstract 6 Tack till Daniel Persson för illustrationen 3
Problem: Harry har implementerat en ringbuffer med en cirkulärt länkad lista för datatypen heltal Han vill nu använda samma implementation igen, men den här gången för strängar. Hur löses uppgiften utan att kopiera all kod för varje framtida ny datakod? 7 En lösning: Använd polymorfism och spara alla datatyper som en Object. Alla klasser är ju en Object public class MyCircularLinkedListNode{ Object data; MyCircularLinkedListNode next; Fungerar, men kräver en explicit castning (typomvandling) varje gång ett element ska hämtas //and what if the data really isn t a String.. String data = (String) ringbuffer.remove(); 8 4
Generiska klasser Bättre lösning: Generiska klasser Mall för klasser Exakta utseendet definieras först när klassen används public class MyLinkedListNode<T>{ T data; MyLinkedListNode<T> next;... MyLinkedListNode<String> node =new MyLinkedListNode<String>();... String text = node.data; //no casting needed, data is already String 9 Generiska klasser(2) Fördelar: Explicit castning undviks Bättre möjlighet för kompilatorn att kontrollera typer -> fler buggar upptäcks vid kompilering Tydligare kod Blir ett sätt att tvinga programmeraren att göra rätt 10 5
Generiska klasser(3) Ibland uppstår behov av att begränsa vilka typer en generisk klass kan instantieras med (tydlighet) public class MyLinkedListNode<T extends Animal>{... MyLinkedListNode kan nu bara spara Animal och dess subklasser MyLinkedListNode<Cat> node = new MyLinkedListNode<Cat>(); //ok //NO. String is not a subclass of Animal! MyLinkedListNode<String> node = new MyLinkedListNode<String>(); 11 Jokertecken (en. wildcards) Ibland vet man inte exakt typ, men behöver ändå ange en /* Ugly code */ public void printallanimals(list theanimals){ for(object o : theanimals){ ((Animal)o).presentYourself(); /* Beautiful!*/ public void printallanimals(list<? extends Animal> theanimals){ for(animal a : theanimals){ a.presentyourself(); 12 6
Jokertecken (en. wildcards)(2) Exempel: generisk klass och jokertecken public interface List<E>{ public void addall(collection<? extends E> c); public boolean containsall(collection<?> c); Samma resultat som <? extends Object> 13 Undantag (en. Exception) Anger något som hänt som ligger utanför normal körning Felaktig indata Körfel Hårdvarufel I Java är undantag objekt 14 7
Undantag (en. Exception)(2) Definiera undantag public class WordNotFoundException extends Exception{ private String word; public WordNotFoundException(String word){ super( Could not find the word + word); this.word = word; public String getword(){ return word; 15 Undantag (en. Exception)(3) Använda undantag public E lookup(string key) throws WordNotFoundException{ for(int i = 0; i < last; i++){ if(contents[i].getkey().equals(key)){ return contents[i].getvalue(); throw new WordNotFoundException(key);... Dictionary<String> dictionary = new ArrayDictionary<String>(); try{ String translation = dictionary.lookup( Hej ); catch(wordnotfoundexception e){ System.out.println(e.getMessage()); Notera: Undantag av typen RuntimeException kräver inte throws, try, catch 16 8
Undantag (en. Exception)(4) Fånga undantag Dictionary<String> dictionary = new ArrayDictionary<String>(); Car anderscar = new Car(); try{ anderscar.drive(); catch(nofuelexception e1){ anderscar.refill(); catch(engineoverheatedexception e2){ anderscar.stop(); throw e2; 17 9