objektorienterad programmeringweb.abo.fi/~pbostrom/kurser/sysdes/presentation2.pdfobjektorienterad...
TRANSCRIPT
Objektorienterade mekanismer
n För att kunna designa bra objektorienterad mjukvara måste man känna till vilka funktioner som OO-programmeringsspråk erbjuder
n Klasser för att definiera typer av objekt¤ Väldefinierad gränssnitt¤ Döljning av information
n Nedärvning (inheritance) kan används för att skapa subtyper av objekt¤ Omdefiniera metoder¤ Addera mera metoder och attribut
n Gränssnitt (Interface)¤ Definiera hur ett objekt kan användas
n Typ-parametrisering kan användas för att skapa typmönster¤ Samma kod kan användas för många olika typer av objekt
Programmeringspråk
n Java är huvudspråk i kursen
n Bokens exempel är dock ofta C++¤ Skillnaden inte speciellt stor i det här fallet¤ Java versioner presenteras på föreläsningarna
Klass definition
n Som alla vet kan en klass definition se ut så här i java¤ Exempel...
n En klass har¤ metoder (klass- och instans)¤ variabler (klass- och instans)¤ konstanter¤ inre och anonyma klasser¤ Dessa kan vara synliga, skyddade eller privata (public,
protected eller private)
Ärvningn Om klass B är en subtyp av klass A
n Klass B får tillgång till alla metoder och variabler som är deklareradesom public eller protected i A
n En subklass kan fritt omdeklarera metoder och variabler som den kan nå
����� ��
�����������������
���
�
����� � �� ��� ��
�����������������
���
�
Ärvning
n Gemensam funktionalitet för flera klasser kan placeras i en superklass¤ Behöver inte upprepa kod¤ Kod kan återanvändas
n Kan användas för att ge abstrakt definition av flera liknande klasser¤ Polymorfism – Flera olika typer av objekt har olika
implementationer av samma metoder¤ En användare av listor behöver inte bry sej om listan är
implementerad som en länkad lista eller som en array - Sammafunktionalitet
Exempel: En liten del av swing paketet
Container
JComponent
AbstractButton
JButtonJMenuItem JToggleButton
Box JFileChooser
PanelScrollP ane
Ärvning (forts)
n I Java så ärver alla objekt av klassen java.lang.Object
n Denna klass innehåller en del användbara metoder¤ clone –omdefinieras för att skapa kopior av ett objekt (djup
kloning)¤ equals – omdefinieras för att ge en definition på likhet mellan två
objekt¤ getClass – Returnerar klassen för objektet¤ hashCode – gör att objekt kan användas i hashtabeller. Måste
vanligen omdefinieras¤ toString – Returnerar en sträng representation av objektet.
Omdefinieras vid behov¤ + ett antal metoder för synkronisering i multi-trådade program
Gränssnitt (Interfaces)
n En klass i Java kan bara ärva av en annan klass¤ Ofta behöver en klass implementera flera abstrakta klasser
n I Java har man gränssnitt (interfaces)¤ Ger bara gränssnittet för en klass¤ Innehåller inte implementationer av metoder
n Interface för en stack (LIFO-lista) kan vara:
��������� ���� �� ��
������������������ ������
������ ���� �������
������ ���� �������
�
Gränssnittn En klass kan implementera flera gränssnitt.
n En användare av en stack behöver bara veta om gränssnittet, inte den exakta implementationen
����������� �� ��������� � ��� �� ������������
�������� ������������
������������������ ����������
���
��������� �����������
�
������������� ����
���� �����������
���
�
Gränssnitt vs Ärvning
n Liknande mekanismer¤ C++ har inga gränssnitt¤ Men har multipel ärvning i stället
n Multipel ärvning har ett problem:
n Gränssnitt har inte problemet och ger i många fall elegantare lösningar
n Ärvning ska användas med försiktighet, diskuteras mera senare
A
m1()m2()
B
m1()m2()
C
m1()m2()
D
Ett problem
n Alltså, typ information går förlorad när man sätter heltalet på stacken ¤ Omöjligt att hitta typfel under kompilering¤ Man måste själv hålla reda på typ konvertering¤ Gör koden mindre läsbar (kan inte se på stacken vad den
innehåller)n Skulle vara bra om typ informationen bevaras
�� ���� � �� ��������
�������� � ������ �!���
�������� � � "���#$������#��
������ "�������� ���������
Lösning
n Klasser kunde parametriseras med typer som argument
n Typ korrekthet kan nu checkas under kompilering
n Det är nu också möjligt att veta typen på objekt som stacken innehåller, genom att kolla variabel deklarationen
�� �%������ &��� � �� �����%������ &���
�������� � ������ �!���
������ "���������
Typ-parametrisering
n Statisk (parametrisk) polymorfism
n Möjlighet at definiera klasser med en typ parameter har länge varit möjligt i C++¤ Java stöder också detta sedan version 1.5
n Möjligt att skriva klasser som kan användas för många olika klasser av objekt¤ Är typsäker
n
Ärvning/typ parametrisering
List_of_people
Linked_list_of_books
Set_of_books
List_of_journals
List_of_books
typ parametriseringtyp parametrisering
abstraktion
specialisering
Definition av generell stack
n Typ-parameter betecknas helst med en stor bokstav (E, T,... )
������ ��� ���� '�� �%(&�
������ ��������(�����
������ (������
������ (������
�
'�� �%� "��&��� ��� � ���
��� �������#$������#��
� "���� ���� ��������
Subtyper
n Fungerar det här korrekt?
n Här pekar ls och lo till samma lista. Objektet som returneras är inte av typ String
n Detta är alltså inte korrekt
)"��%� "��&���� � � �*)"��%� "��&���
)"��%���� �&�����
����++�� � ���� �����
� "�����������,��
Sub typer (forts)
n Om Foo är en subtyp av Bar och G är en generell typ deklaration
n Då är inte G<Foo> en subtypav G<Bar>
n Det här gör mekanismen lite onödigt strikt...
Foo
Bar G<B ar>
G<Foo>
Jokertecken
n Tyvärr funkar koden ovanför bara för samlingar av objekt av typ Object och inte för samlingar av alla typer av objekt som tänkt
���� "������� �"�������� �"��%���� �& ��
�������� ��- ��
*���������� "��������
�
�
���� "������� �"�������� �"��%�& ��
�������� ��- ��
*���������� "��������
�
�
Jokertecken (forts)
n Tecknet ? står för en okänd typ
n Genererar kompileringsfel¤ Eftersom man inte vet vilka element typer c har kan man inte
sätta till element¤ Collection<?> kan stå för Collection<String>,
Collection<Integer>, etc...
����� �"��%.& ���/� �*)"��%� "��&
��++�� � ���� �����
Mera joker tecken������������������� �����
�����������������+ �/����0�� ��
�
����������� �" �� �� ��� ���������
����������� 1� ������ �� ��� ���������
���������+ �/����)"��%� �� ��� ����&��������
���������-��������
��+ �/� ��0����
�
�
Begränsade joker tecken
n <? extends Shape> ger en övre gräns Shape för ?¤ ? är nu ett begränsat joker-tecken
n Funkar detta?¤ List<? extends Shape> kan representera List<Circle>
����������++1� �������)"��%� �� ��� ����&��������
��������++�,�� � 1� ����������
�
Funktion tillsammans med gammal kod
n Typ parametrisering i Java är relativt nytt¤ Det finns mycket Java kod som inte använder den här
mekanismen¤ Parametriseringen måste fungera ihop med gammal kod
n Collection är inte samma som Collection<Object>
Man kan fuska
n Detta genererar en varning då koden kompileras, jämför med
n Resultat då koden ovan körs är det samma i båda fallen (ClassCastException)
������ � "����������������� 2��
)"��%� "��&*��� � )"���+)"��%� "��&��
)"��2��*��
2���++�2��
� ����*������,��
������ � "����������������� 2��
)"��*��� � )"���+)"����
)"��2��*��
2���++�2��
� ����*������,��
Mera information
n En bra tutorial om Java typ-parametrisering finns här:¤ java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
Samlingar (Collections)
n Collections, eftersom de kan användas för att spara olika typer av data¤ Implementerar Collections gränssnittet¤ Finns implementerade för många vanliga data strukturer¤ Java.util paketet¤ I Java 5 använder typ parametrisering för att få typsäkra samlingar
n Behöver inte själv implementera datastrukturer för att spara data¤ Snabbare implementering¤ Kan lätt byta datastruktur för att få maximal snabbhet
n Bra inspirationskälla för att se hur man skriver återanvändbar kod
Collections (forts)
n Baserar sej på gränssnittet Collection ¤ Samlingar av element¤ Baserar sej på användande av metoder som finns för varje element (till
exempel equals för avgöra likhet)
n Fem subgränssnitt¤ Set - Interface för hantera mängder av element¤ List – För att hantera listor av element¤ SortedSet –Gränssnitt för att hantera mängder vars element är
sorterade¤ Queue – Gränssnitt för att spara element före processering¤ BlockingQueue – För parallella program
Gränssnittet Collectionpublic interface Collection<E> extends Iterable<E> { // Basic operations int size(); boolean isEmpty(); boolean contains(Object element); boolean add(E element); //optionalboolean remove(Object element); //optionalIterator<E> iterator(); // Bulk operations boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); //optionalboolean removeAll(Collection<?> c); //optionalboolean retainAll(Collection<?> c); //optionalvoid clear(); //optional// Array operations Object[] toArray(); <T> T[] toArray(T[] a); }
Iteratorer
n Iteratorer används för att komma åt element i samlingar (Collections)¤ Behöver inte känns till strukturen av samlingen (access med
index eller genom referenser)¤ Kan användas för att iterera över element i samlingar
public interface Iterator<E> {boolean hasNext(); E next(); void remove(); //optional
}
Iteratorer (forts)
n hasNext()¤ Returnerar sant om iterationen har mera element
n next()¤ Returnerar nästa element i iterationen
n remove()¤ Tar bort det element från iterationen som var senast returnerat
från next()¤ Kan anropas bara en gång för varje anrop till next()¤ Det enda säkra sättet att ta bort element från en samling när
man itererar över denn Beteendet ospecifierat om en samling ändrar under iterering
Iteratorer - litet exempel
n Kod för att filtrera bort element i en samling
static void filter(Collection<?> c) { for (Iterator<?> it = c.iterator(); it.hasNext(); )
if (!cond(it.next())) it.remove();
}
For-each
n Ny loop typ i Java 1.5¤ Används för att iterera över all element i en samling c
n c måste implemenetera Iterable gränssnittet
for (Object o : c){ //Gör något med o...
}
public Interface Iterable<T>{
Iterator<T> iterator();
}
Iteratorer vs. for-each
n For-each är i princip samma som
n Iteratorer måste användas¤ Då man vill ta bort element - For-each döljer iteratorn så element
kan inte tas bort.¤ Iterera över flera samlingar samtidigt¤ Mera flexibelt
for( Iterator<E> it=c.iterator(); it.hasNext(); E o=c.next()){...
}
for(E o : c){...
}
Operationer på samlingar
n containsAll(Collection<?> c) – returnerar sant om all element i cfinns i samlingen
n addAll(Collection<? extends E> c) – lägger till alla element i c till samlingen
n removeAll(Collection<?> c) – tar bort alla element ur samlingen som finns i c
n retainAll(Collection<?> c) – tar bort alla element ur samlingen som inte finns i c
n clear() – tar bort alla element ur samlingen
n addAll, removeAll, retainAll returnerar true om samlingen var modifierad
Mängder
n Gränsnittet Set<T> beskriver mängder¤ Inte två likadana element
Set<T> union = new HashSet<T>(s1); union.addAll(s2);
Set<T> intersection = new HashSet<T>(s1); intersection.retainAll(s2);
Set<T> difference = new HashSet<T>(s1); difference.removeAll(s2);
Mängdoperationer - exempel
n Ta bort alla instanser av objektet e ur samlingen c
n Skapa en ny samling som har samma element som c men utan duplikat
n Samma sak men bevara ordningen på elementen
c.removeAll(Collections.singleton(e))
Collection<T> noDups = new HashSet<T>(c);
Collection<Te> noDups = new LinkedHashSet<T>(c);
Mängdexempelimport java.util.*; public class FindDups {
public static void main(String[] args) { Set<String> s = new HashSet<String>(); for (String a : args)
if (!s.add(a)) System.out.println("Duplicate detected: " + a);
System.out.println(s.size() + " distinct words: " + s); }
}
>java FindDups i came i saw i left
Duplicate detected: i Duplicate detected: i 4 distinct words: [i, left, saw, came]
Listor
n Listor är ordnade samlingar (sekvenser). De kan innehålla duplikat
n Implmenterar gränsnittet List<T>n Access med hjälp av position
¤ Manipulera element med hjälp av den numeriska positionenn Sökning
¤ Sök efter ett element och returnera den numeriska positionenn Iterering
¤ Ny iterator som tar i beaktande de sekventiella naturen hos listorn Range-view
¤ Kan göra operationer på intervaller.
Listor - exempel
n Skapa en ny lista som består av konkateneringen av två listor
n By ut två element
List<T> list3 = new ArrayList<T>(list1); list3.addAll(list2);
public static <E> void swap(List<E> a, int i, int j) { E tmp = a.get(i); a.set(i, a.get(j)); a.set(j, tmp);
}
Mera listexempel
n Ordna elementen i slumpmässig ordning
public class Shuffle { public static void main(String[] args) {
List<String> list = new ArrayList<String>(); for (String a : args)
list.add(a); Collections.shuffle(list, new Random()); System.out.println(list);
} }
Iteratorer för listor
public interface ListIterator<E> extends Iterator<E> { boolean hasNext(); E next(); boolean hasPrevious(); E previous(); int nextIndex(); int previousIndex(); void remove(); //optional void set(E e); //optional void add(E e); //optional
}
Listor - exempel
n Söka från slutet
for (ListIterator<Type> it = list.listIterator(list.size()); it.hasPrevious(); ) {
Type t = it.previous(); ...
}
Listor - index
n Iterator har en kursor som ger position i listan
n next returnerar elementet till höger om kursornn previous returnerar elementet till vänstern nextIndex returnerar indexet för next, previousIndex index för
previous¤ nextIndex-previousIndex=1
Sublistor
n Kan skapa sublistor¤ Listorna presenterar en vy av en lista¤ Sublistor kan användas som vanliga listor¤ Förändringar i sublistan syns i orginallistan¤ List<E> subList(int fromIndex, int toIndex)¤ Eliminerar behovet för explicita intervalloperationer
n Radera ett intervall av elementlist.subList(from, to).clear();
Sublistor - exempel
n Dela ut en hand från en kortpacke
public static <E> List<E> dealHand( List<E> deck, int n) { int deckSize = deck.size(); List<E> handView = deck.subList(deckSize - n, deckSize); List<E> hand = new ArrayList<E>(handView); handView.clear(); return hand;
}
class Deal { public static void main(String[] args) {
int numHands = Integer.parseInt(args[0]); int cardsPerHand = Integer.parseInt(args[1]); // Make a normal 52-card deck.
String[] suit = new String[] {"spades", "hearts", "diamonds", "clubs"}; String[] rank = new String[] {"ace","2","3","4","5","6","7",
"8", "9","10","jack","queen","king"};
List<String> deck = new ArrayList<String>();
for (int i = 0; i < suit.length; i++) for (int j = 0; j < rank.length; j++)
deck.add(rank[j] + " of " + suit[i]); Collections.shuffle(deck);
for (int i=0; i < numHands; i++)System.out.println(dealHand(deck, cardsPerHand)); } }
Sublistor - sammafattning
n Mycket använbara
n Beteendet odefinierat för en sublista om element sätts till eller tas bort från den ursprungliga listan på något annat sätt än viasublistan
n Sublistor bör endast användas som tillfälliga objekt för att göra något på intervall av listor
Klassen Collections
n sort —Sortera listann shuffle —Slumpmässigt permutera elementen i listann reverse — Svänger om ordningen i listann rotate —Roterar listan runt en axel. n swap —Byter ut valda element i listan. n replaceAll —Ersätter alla förekomster av ett önskat element med ett annat. n fill — Skriver över alla element i listan med ett önskat värde. n copy —Kopierar en käll-lista till en destinationslista. n binarySearch —Gör en binärsökning på en sorterad lista. n indexOfSubList — Returnerar index of första sublistan som matchar. n lastIndexOfSubList — Returnerar index of sista sublistan som matchar.
Map
n En relaterat gränssnitt är Map¤ Associerar en nyckel med ett värde¤ Till exempel Hashtabeller är Maps¤ En nyckel associeras med högst ett element¤ Matematiskt en (partiell) funktion
Mappublic interface Map<K,V> { // Basic operations V put(K key, V value); V get(Object key); V remove(Object key); boolean containsKey(Object key); boolean containsValue(Object value); int size(); boolean isEmpty();
// Bulk operations void putAll(Map<? extends K, ? extends V> m); void clear();
// Collection Views Set<K> keySet(); Collection<V> values(); ...
Map exempel
n Beräkna frekvensen för ordpublic class Freq {
public static void main(String[] args) { Map<String, Integer> m = new HashMap<String, Integer>(); // Initialize frequency table from command line for (String a : args) {
Integer freq = m.get(a); m.put(a, (freq == null) ? 1 : freq + 1);
} System.out.println(m.size() + " distinct words:"); System.out.println(m);
} }
Resultat
>java Freq if it is to be it is up to me to delegate
8 distinct words: {to=3, delegate=1, be=1, it=2, up=1, if=1, me=1, is=2}
Mera exempel
n Map med attribut-värde par
n Attribut som är tillåtna
n Attribut som krävs
static <K, V> boolean validate(Map<K, V> attrMap, Set<K> requiredAttrs, Set<K>permittedAttrs) {
boolean valid = true; Set<K> attrs = attrMap.keySet(); if(!attrs.containsAll(requiredAttrs)) {
Set<K> missing = new HashSet<K>(requiredAttrs); missing.removeAll(attrs); System.out.println("Missing attributes: " + missing); valid = false;
} if (!permittedAttrs.containsAll(attrs)) {
Set<K> illegal = new HashSet<K>(attrs); illegal.removeAll(permittedAttrs); System.out.println("Illegal attributes: " + illegal); valid = false;
} return valid;
}
Sortering
n Collections.sort
n Elementen i listan som ska sorteras måste kunna jämföras¤ Implementera gränssnittet Comparable¤ Ett skillt jämförarobjekt. Ett objekt som implementerar
Comparator gränssnittet