Objektorienterad programmeringsmetodik Generics, clone Generics Återanvändning Ännu ett sätt att lösa ett gammalt problem: skriva så lite kod som möjligt Vi vill ha metoder som fungerar på olika klasser Hur implementerar vi då egna generiska klasser/metoder? Vi vill egentligen ha: Lista av heltal Lista av strängar Lista av... Lista av våra egna objekt Återanvända algoritmer för olika datatyper 3 4 Generisk klass med typparameter Inre klass - ListIterator import java.util.iterator; public class GenericList<T> implements Iterable<T> // Element is an inner class that contains values of type K private class Element<K> private K value; private Element<K> next; public Element() value=null; next=null;... 5 // The (inner class) ListIterator is used to iterate over elements<t> private class ListIterator implements Iterator<T> Element next; public ListIterator(Element first) next=first; public boolean hasnext() return next.next()!=null; public void remove() throw new UnsupportedOperationException(); public T next() next=next.next(); return next.value(); 6 1
GenericList GenericList // First element in the generic list private Element<T> first; public GenericList() first = new Element<T>(); public boolean isend(element<t> elem) return elem.next() == null; public Element<T> first() return first; public Element<T> next(element<t> elem) return elem.next(); public T inspect(element<t> elem) return (T) elem.next().value(); public void insert(t value, Element<T> elem) Element<T> newelem=new Element<T>(value, elem.next()); elem.setnext(newelem); public void remove(element<t> elem) elem.setnext(elem.next().next()); public Iterator<T> iterator() return new ListIterator(first); 7 8 Testkod // Test code public static void main(string[] args) GenericList<Integer> intlist=new GenericList<Integer>(); intlist.insert(1, intlist.first()); intlist.insert(2, intlist.first()); intlist.insert(3, intlist.first()); intlist.insert(4, intlist.first()); for(int i:intlist) System.out.println(i); Generisk metod med typparameter static <T> void arraytocollection(t[] arr, Collection<T> coll) for (T obj : arr) coll.add(obj); // Correct GenericList<String> stringlist = new GenericList<String>(); stringlist.insert("text 1", stringlist.first()); stringlist.insert("text 2", stringlist.first()); for(string i : stringlist) System.out.println(i); 9 10 Problem med typkonvertering public static void main(string[] args) GenericList<String> s1 = new GenericList<String>(); s1.insert(new String( hej ), s1.first()); String s = s1.inspect(s1.first()); Kod som fungerar på alla generiska klasser? Till exempel skriva ut alla saker i listan GenericList<Object> o1 = new GenericList<Object>(); GenericList<Object> o2 = s1; Type mismatch: cannot convert from GenericList<String> to GenericList<Object> 11 12 2
Innan generics import java.util.linkedlist; import java.util.list; public class Demo4b public static void main( String argv[] ) LinkedList l = new LinkedList(); import java.util.linkedlist; import java.util.list; Nu public class Demo4b public static void main( String argv[] ) LinkedList<String> l = new LinkedList<String>(); public static void printstuff( List sl ) while(!sl.isempty() ) System.out.println( o ); 13 public static void printstuff( List<Object> sl ) while(!sl.isempty() ) Demo4b.java:9: printstuff(java.util.list<java.lang.object>) in Demo4b cannot be applied to System.out.println( o ); (java.util.linkedlist<java.lang.string>) ^ 1 error 14 Vilken lista som helst -? Problem public class Demo4b public static void main( String argv[] ) LinkedList<String> l = new LinkedList<String>(); Kompilatorn kan inte garantera vilken typ o är public static void printstuff( List<?> sl ) while(!sl.isempty() ) System.out.println( o ); Typen för sl är okänd men tilldelas till en String 15 16 Specifikt för vissa klasser Problem för andra listor Man vill göra något med listor av grafiska objekt Vad skall dousefulshapestuff göra med en String? 17 18 3
Begränsa typen Åt andra hållet Ta bara emot listor med Shape och subtyper Det går även att begränsa en Generisk typ åt andra hållet Görs mha super TreeSet(Comparator<? super E> c)? svarar i detta fall mot en godtycklig superklass till E 19 20 Generiska arrayer Värt att veta Java tillåter inte skapandet av arrayer av generisk typ Exvis public class Stack<E> private E[] data = new E[10];... är ej tillåtet Lösningen: Skapa en array av Objects och typkonvertera denna public class Stack<E> private E[] data = (E[]) (new Object[10]);... Fast det genererar en varning från kompilatorn :-( 21 Alla instanser av en generisk klass delar samma kod En del andra språk kompilerar upp en ny version av koden för varje instans av den generiska klassen (och ibland värre än så!!) 22 Generics i Java 7 Klona objekt En ny Diamant operator List<String> list = new LinkedList<>(); I detta fall så kommer java att för konstruktorn göra ett antagande att det är LinkedList<String>(); som ska köras. Diamantoperatorn kan användas så länge som Java kan lista ut vilken typ som menas i sammanhanget. Följande funkar tex inte: List<String> list = new ArrayList<>(); list.add("a"); list.addall(new ArrayList<>()); Göra en kopia av ett objekt Definerad i Object protected Object clone() throws CloneNotSupportedException Kan behöva implementeras i din klass Eftersom addall i detta fall förväntar sig en collection som innehåller en String eller en subklass till den (och inte kan avgöra typen). 23 24 4
Grund/djup Grund kopia Grund SomeClass Djup OtherClass SomeClass SomeClass OtherClass SomeClass OtherClass En egen clone-metod, i detta fall anropar den bara basklassens metod public class SomeClass implements java.lang.cloneable private OtherClass oc; public Object clone( ) throws java.lang.clonenotsupportedexception return super.clone(); Obs Cloneable-interfacet 25 26 Djup kopia Klonbara objekt I detta fall måste metoden själv kopiera den information som skall följa med public class SomeClass implements java.lang.cloneable private OtherClass oc; // detta måste också as! public Object clone( ) throws java.lang.clonenotsupportedexception SomeClass sc = (SomeClass) super.clone(); sc.oc = (OtherClass) oc.clone(); return sc; Implementera java.lang.cloneable Undantaget java.lang.clonenotsupportedexception kastas om man anropar Object.clone() för ett objekt som inte implementerar Clonable-interfacet clone i Object är definierad protected men man brukar omdefiniera den med en public clone metod Klona attribut som är objekt Klona inte objekt som är immutable Anropa super.clone för att a föräldraobjekts parametrar (och för att objects clone() ska ta hand om primitiva typer och referenser) 27 28 5