56
Objektorienterad programmering

Objektorienterad programmeringweb.abo.fi/~pbostrom/kurser/sysdes/presentation2.pdfObjektorienterad programmering Objektorienterade mekanismer n För att kunna designa bra objektorienterad

  • Upload
    others

  • View
    6

  • Download
    0

Embed Size (px)

Citation preview

Objektorienterad programmering

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� ����������

Mera exempel

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

Mera information

n Tutorial för Collections¤ http://java.sun.com/docs/books/tutorial/collections/index.html¤ Då speciellt kapitlet ”Interfaces”

n Java 5 och 6 api dokumentation ¤ http://java.sun.com/j2se/1.5.0/docs/api/¤ http://java.sun.com/javase/6/docs/api/