Mer om arv. Kap J7-1 • I Java självt är arv frekvent förekommande. Två exempel är exceptions och components (awt). • Arv bygger normalt på en IS-A-relation. – Button IS-A Component . – NullPointerException IS-A RuntimeException. • Polymorfism och dynamisk bindning. • Återanvändning av kod. ArrayIndexOutOfBoundsException IndexOutOfBoundsException RuntimeException StringIndexOutOfBoundsException Exception NullPointerException EOFException IOException (superklass) FileNotFoundException (subklass) Klassen Shape 9/25/0 0 Kap J7-2 public abstract class Shape { private String name ; abstract public double area( ); public Shape( String shapeName ) { name = shapeName ; } final public boolean lessThan( Shape rhs) { return area( ) < rhs.area( ); } final public String toString( ) { return name + " of area " + area( ); } } 9/25/0 0 Kap J7-3 Klasserna Circle Rectangle och Square. public class Circle extends Shape { private double radius ; private static final double PI=3.141592; public Circle (double rad) { super( ” circle " ); radius = rad; } public double area( ) { return PI * radius * radius ; } } public class Rectangle extends Shape{ private double length; private double width; public Rectangle (double len, double wid) { super( "rectangle " ); length = len; width = wid; } public double area( ) { return length * width; } } public class Square extends Rectangle { public Square(double side) { super(side , side); } } 9/25/0 0 1 Referenser till subklasser. Kap J7-4 • Regel: Om värde av typen ”ref till basklass” krävs, kan man ge uttryck av typen ”ref till subklass”. • Regel: En referensvariabel som har typen ”referens till basklass” får referera även till objekt som är av ”subklasstyp”. Rectangle rec= new Rectangle (1,2); Square sq= new Square(3); Shape sh; sh=rec; sh=sq; rec=sq;// alla är ok! sq=rec // ej tillåtet sq= (Square) rec; //ok med explicit typomvandling if (rec instanceof Square) //Bättre! sq= (Square) rec; 9/25/0 0 Typer av metoder i en klass. Kap J7-5 • Fyra typer av metoder – Final metoder • Används när metoden är oföränderlig (invariant) över klasshierkin . • Statisk bindning. – Abstrakta metoder • superklassen har ingen implementation och är abstrakt. Medför att subklasser måste implementera den eller själva bli abstrakta. • Dynamisk bindning. – Statiska metoder • inget kontrollerande objekt. • Statisk bindning. – Övriga metoder • superklassen ger en defaultimplemetation som av subklasserna antingen överskuggas eller accepteras som den är. • Dynamisk bindning. 9/25/0 0 Sortering av figurer (Shapes). Kap J7-6 • Problemformulering: – Läs N st figurer (cirklar, rektanglar, kvadrater) och skriv ut dem sorterade efter area. • I följande program finns exempel på – Polymorfism och dynamisk bindning. – Konstruktorer vid arv. 9/25/0 0 2 Klassen TestShape Kap J7-7 import java.io .*; class TestShape { private static BufferedReader in; private static void insertionSort(Shape [ ] a ) { for( int p = 1 ; p < a .l ength; p++ ) { int j = p; Shape tmp = a[ p ]; for(;j>0 && tmp. lessThan(a[j-1]); j-- ) a[ j ] = a[ j - 1 ]; a [ j ] = tmp; } } 9/25/0 0 Klassen TestShape, forts. Kap J7-8 public static void main(String[] args) { try { // Get # of shapes System.out.println( "Enter #of shapes"); in=new BufferedReader( new InputStreamReader(System.in)); int numShapes= Integer.parseInt(in.readLine() ); // Read the shapes Shape[] array=new Shape[numShapes]; for( int i = 0; i < numShapes; i++ ) array[ i ] = readShape( ); insertionSort( array ); //Sort and output System.out.println( " Sorted by area:" ); for( int i = 0; i < numShapes; i++ ) System. out.println( array[ i ] ); } catch(Exception e) { System.out.println( e ); } } 9/25/0 0 Klassen TestShape, forts. Kap J7-9 private static Shape readShape( ) { double rad, len, wid; String oneLine; try { System.out.println( "Enter shape type:" ); do { oneLine = in.readLine( ) ; } while ( oneLine. length( ) == 0 ); switch( oneLine.charAt( 0 ) ) { case 'c': System.out.println( " Enter radius:"); rad = Double .valueOf( in.readLine()).doubleValue(); return new Circle (rad ); case 's': System.out.println( " Enter side: " ); len= Double .valueOf(in.readLine()).doubleValue(); return new Square(len); case 'r': System.out.println("Enter length and width ” + "on separate lines: "); len = Double .valueOf( in.readLine( ) ) .doubleValue( ); w i d =Double .valueOf(in.readLine()).doubleValue(); return new Rectangle (len,wid); default : System.err .println( "Need c, r, or s" ); return new Circle ( 0 ) ; } } catch( IOException e ) { System.err.println( e ); return new Circle ( 0 ); } } 9/25/0 0 3 En körning Kap J7-10 D:\minaprog>java TestShape Enter #of shapes 4 Enter shape type: r Enter length and width on separate lines : 4 5 Enter shape type: r Enter length and width on separate lines : 3 6 Enter shape type: s Enter side: 5 Enter shape type: c Enter radius: 2.5 Sorted by area: rectangle of area 18.0 circleof area 19.634954084375 rectangle of area 20.0 rectangle of area 25.0 D:\minaprog> 9/25/0 0 Varför super final? Kap J7-11 • Det reserverade ordet super används för att – anropa överskuggade metoder. – komma åt dolda instansvariabler. – anropa superklassens konstruktor. • Obs! Måste ligga som första sats i subklassens konstruktor! • Det reserverade ordet final anger att – en metod inte får överskuggas. • gäller även private- och static-deklarerade metoder. – en klass är slutgiltig, d v s får inte ärvas. • Metoden finalize är definierad i Object-klassen. – anropas automatiskt precis innan ett objekt utsätts för g.c. – används för att låta objektet ”städa upp efter sig”, släppa systemresurser etc. – T ex public void finalize () throws Throwable { infil.close (); super. finalize (); //sker ej med automatik } 9/25/0 0 En egendefinierad kö. Kap J7-12 // Queue class // // Konstruerad utan initierare // // ******************Publika operationer********************* // void enqueue( x ) --> Sätt in x // Object getFront( ) --> Returnera äldsta elementet // Object dequeue( ) --> Returnera och ta bort äldsta elementet // boolean isEmpty( ) --> Returnera true if tom; annars false // void makeEmpty( ) --> ta bort alla elementet // ******************Fel***************************************** // getFront eller dequeue på en tom kö /** * List-baserad implementation av kö. */ public class Queue { private ListNode front; private ListNode back; 9/25/0 0 4 Kö forts. Kap J7-13 /** * Konstruera kön. */ public Queue( ) { front= back=n u l l; } /** * Testa om kön är tom (logiskt sett). * @returnera true om tom, annars false . */ public boolean isEmpty( ) { return front == null; } /** * Gör att kön är tom (logiskt sett). */ public void makeEmpty( ) { front = null; back = null; } 9/25/0 0 Kö forts. Kap J7-14 /** * Returnera äldsta elementet i kön. * Ändrar ej kön. * @ return the least recently inserted itemin the queue. * @ exception Underflowom kön är tom. */ public Object getFront( ) throws Underflow { if( isEmpty()) throw new Underflow( "Queue getFront" ); return front.element; } /** * Returnera och ta bort äldsta elementet i kön. * @Returnera och ta bort äldsta elementet i kön. * @ exception Underflowom kön är tom. */ public Object dequeue( ) throws Underflow { if( isEmpty( ) ) throw new Underflow( "Queue dequeue" ); Object returnValue = front.element; front = front.next; return returnValue; } 9/25/0 0 Kö forts. Kap J7-15 /** * Sätt in ett nytt element i kön. * @ p a r a mx är det nyaelementsom sätts in. */ public void enqueue( Object x ) { if( isEmpty( ) ) // Make queue of one element back = front = new ListNode( x ); else // Regular case back = back.next = new ListNode( x ); } } } 9/25/0 0 5 Klass ListNode Kap J7-16 // Bas -nod lagrad i en länkad lista. // Är tänkt att inte vara nåbar utanför // det aktuella paketet class ListNode { // "Friendly data"; accessbara av // rutiner i samma paket Object element; ListNode next ; // Konstruktorer ListNode( Object theElement ) { this( theElement, null ); } ListNode(Object theElement,ListNode n) { element = theElement; next = n; } } 9/25/0 0 Exceptionklassen Underflow Kap J7-17 /** * Exception class for access in empty * containers such as stacks, queues , * and priority queues . */ public class Underflow extends Exception { /** * Construct this exception object . * @ param message the error message. */ public Underflow ( String message ) { super( message ); } } 9/25/0 0 Klassen QueueTest Kap J7-18 import java. util .*; class QueueTest { public static void main (String[] args) throws Underflow { Queue q = new Queue(); q.enqueue(new Circle (12)); q.enqueue(new Square(12)); Object o = q.dequeue ( ); System.out .println (o + " blir servad"); q.enqueue(new Square(2)); q.enqueue(new Rectangle(1,2)); o = q.dequeue( ); System.out .println (o + " blir servad"); q.enqueue(new Circle (2)); System.out .println ("Först i kön står nu ” + q.getFront()); while (!q. isEmpty()) { o = q.dequeue( ); System.out .println (o + " blir servad"); } //nu blir det underflow!!!!! o = q.dequeue( ); } 9/25/0 0 } 6 Exekvering Kap J7-19 D:\minaprog \java\ohtester \Shape>java QueueTest circle of area 452.38924800000007 blir servad rectangle of area 144.0 blir servad F÷rst i k÷n st_r nu rectangle of area 4.0 rectangle of area 4.0 blir servad rectangle of area 2.0 blir servad circle of area 12.566368 blir servad Exception in thread "main " Underflow: Queue dequeue at Queue.dequeue( Queue.java:70) at QueueTest.main (Compiled Code) D:\minaprog \java\ohtester \Shape> 9/25/0 0 Kap J7-20 Objektsamlingar och klassen Vector. • Några Vector-metoder – void addElement(Object x) • Add x to the end of the list/vector. – void insertElementAt (Object x, int index) • Insertx at the given index. – void setElementAt (Object x, int index) • Replace the objectat index with x. • Note: The given index must currently be in the list/v ector.) – void removeElementAt(int index) • Removethe indicated element. – void removeAllElements() • Make the list empty . – Object elementAt (int index) • Return the element at index. 9/25/0 0 Klassen Vector, forts. Kap J7-21 • Ytterligare Vector-metoder – int size() • Return the number of elements currently in the vector. – boolean isEmpty() • Return whether the vector is empty . – Vector(int initialCapacity, int incr) • Construct a vector with the indicated initial capacity and add space for incr elements each time the vector is expanded . – Vector(int initialCapacity) • Construct a vector with the indicated initial capacity and double the capacity each time the vector is expanded . – Vector() • Same as Vector(10). 9/25/0 0 7 Vector-exempel Kap J7-22 Vector v = new Vector(); v.addElement("string 2"); v. addElement("string 4"); v.insertElementAt("string 1", 0); v.insertElementAt("string 3", 2); v.addElement("string 5"); for (int i=0; i<v. size(); i++) { String s = (String ) v. elementAt(i); System. out.println (s); } while (!v.isEmpty()) { String s = (String) v.lastElement(); v.removeElementAt(v. size()-1); System. out.println(s); } 9/25/0 0 Vector som kö. Kap J7-23 import java.util. * ; class QTest { public static void main( String[] args) { Vector q = new Vector( ) ; q.addElement(new Square(12)); q.addElement(new q.addElement(new q.addElement(new Circle (12)); q.addElement(new Square(2)); Rectangle(1,2)); Circle (2)); for (int i=0; i<q.size(); i++) { Object o = q.elementAt(i); System. out.println(o); } while (!q.isEmpty()) { System. out.println( ((Shape)q.firstElement()).area() q.removeElementAt(0); } ); } } 9/25/0 0 Exekvering Kap J7-24 C:\phe \java> javac QTest.java C:\phe \java>java QTest circle of area 452.38924800000007 rectangle of area 144.0 rectangle of area 4.0 rectangle of area 2.0 circle of area 12.566368 452.38924800000007 144.0 4.0 2.0 12.566368 C:\phe \java> 9/25/0 0 8 Iteratorer Kap J7-25 • Generell teknik som kan användas för alla datasamlingar. • I Java 1.1 används standardklassen java.util.Enumeration för att beskriva iteratorer. • Metoden elements() används för att skapa en iterator för att löpa igenom vektorn. • Klassen Enumeration har bara två metoder: – hasMoreElements() som returnerar true om det finns komponenter kvar i vektorn (datasamlingen). – nextElement () returnerar nästa komponent i datasamlingen (typ: Object). 9/25/0 0 Användning av iterator. Kap J7-26 import java.util. * ; class QTestE { public static void main( String[] args) { Vector q = new Vector( ) ; q.addElement(new q.addElement(new q.addElement(new q.addElement(new q.addElement(new Circle (12)); Square(12)); Square(2)); Rectangle(1,2)); Circle (2)); for (Enumeration e=q.elements();e.hasMoreElements();) { Object o = e.nextElement(); if (o instanceof Rectangle) System.out.println(o); } while (!q.isEmpty()) { System. out.println( ((Shape)q. firstElement()).area() ); q.removeElementAt(0); } } } 9/25/0 0 Exekvering Kap J7-27 C:\phe\java>javac QTestE.java C:\phe\java>java QTestE rectangle of area 144.0 rectangle of area 4.0 rectangle of area 2.0 452.38924800000007 144.0 4.0 2.0 12.566368 C:\phe\java> 9/25/0 0 9