Grundlagen der Programmierung –Teil1 Einheit VI - 17. Nov. 2010 GDP DDr. Karl D. Fritscher Interfaces • Interfaces bieten in Java ist die Möglichkeit, einheitliche Schnittstellen für Klassen zu definieren, die später oder/und durch andere Programmierer implementiert werden. • Interfaces können von beliebigen Klassen implementiert werden • Eine Klasse kann beliebig viele Interfaces implementieren • Eine Klasse, die ein Interface implementiert, muss alle Methoden des Interface implementieren (oder erben) Die implementierende Klasse garantiert dadurch, dass sie alle Operationen eines Interface anbietet Definition und Implementierung Java-Syntax: interface AnInterface { } class AClass implements AnInterface { } Bsp: Interface definieren interface HasName { String pre = “My Name is “; //Variablen sind autom. static & final! String getName(); //Methoden sind autom. public! //keine Implementierung! } Bsp: Interface implementieren • Der Compiler prüft ob alle Methoden des Interfaces implementiert wurden. class Person implements HasName { private String myName; // Instanzvariable public String getName() { return(pre + myName); // pre stammt aus Interface! } // Methode der Klasse Person public void talk(String sentence) { System.out.println(myName+ “ says: “+sentence); } } … and now for something completely different… Ausnahmebehandlung • Im Ablauf eines Programms können unvorhergesehenen Probleme auftreten. Die JavaVM führt dann eine Ausnahmebehandlung (Exception) durch. • Ausnahmen sind in Java als Objekte definiert, welche Instanzen der Klasse Throwable sind. Zum Beispiel: • java.lang.RuntimeException (unchecked exceptions) • java.io.IOException, • … • Wichtige „Ausnahmezustände“: • Arithmetic Exceptions (bei Division durch 0 bei int) • NullPointerException (Instanzname enthält keine Instanz) • ArrayOutOfBoundsException (unmöglicher Index bei Arrays) • IOException (Ein/Ausgabeproblem) Klassenhierarchie von Exceptions Object Throwable Exception RuntimeException IOException •IndexOutOfBoundExc.•FileNotFoundException •ArithmeticException Exceptions weiterer Packages •EOFException •NullPointerException •CharacterCodingExc. •... •... Exceptions der Klasse RuntimeException und der davon abgeleiteten Klassen sind sogenannte „unchecked exceptions“. Exceptions aller anderen Klassen sind „checked exceptions“ Checked & Unckecked Exceptions • Checked exceptions müssen behandelt werden. Dies wird auch vom Compiler kontrolliert! • Beispiel IOException: public static void main (String[]args)throws IOException { BufferedReader dln = new BufferedReader (new InputStreamReader(System.in)); • System.out.print ("Bitte Zahl eingeben: "); a = Float.parseFloat (dln.readLine ()); … } Bei Verwendung von readline() muss IOException behandelt werden Unchecked Exceptions müssen vom Programmierer nicht unbedingt abgefangen werden. Beispiel für eine RuntimeException class SimpleClass { int s; } class Killer { public static void { SimpleClass mySC mySC= null; mySC.s=10; } } Null-Referenz: Wird einer Referenzvariable, die auf ein gültiges Objekt im Speicher zeigt die null-Referenz zugewiesen, so können keine Methoden und keine Datenfelder mehr über diese Referenzvariable angesprochen werden! main = (String new SimpleClass(); Fehler beim Ausführen und Programm bricht ab: Exception in thread "main" java.lang.NullPointerException: at Killer.main(Killer.java:7) [] args) Beispiel für eine RuntimeException II class Killer2 { public static void main (String { int n=0; int e = 10/n; System.out.println(e); } } Fehler beim Ausführen und Programm bricht ab: Exception in thread "main" java.lang.ArithmeticException: / by zero at Killer2.main(Killer2.java:4) [] args) try & catch try { Anweisungen; } catch(AException e){ Behandlung; } catch(BException e){ Behandlung; } finally { Behandlung; } • try-Block mit Anweisungen die die Exception auslösen kann • catch-Blöcke mit den Fehlerbehandlungsanweisungen (wird nach Typ des Parameters bestimmt!) • finally-Block wird bei jeder Exception am Schluss ausgeführt • Nach der Behandlung der Exception wird das Programm fortgesetzt! Beispiel zu try & catch class Killer3 { public static void main (String [] args) { double myArray[] = new double[5]; // Index double v; int i=5; try { v= myArray[i];// Indexfehler 5>4! }catch(ArrayIndexOutOfBoundsException e) { System.err.println("Folgende Exception ist aufgetreten: " + e); } System.out.println("Weiter geht's ..."); } } 0..4 Exceptions in Methoden class Killer5 { static int divide(int a, int b) throws ArithmeticException { return (a/b); die Methode kann eine (Arithmetic)-Exception auslösen } behandelt diese aber nicht selbst, sondern leitet sie an Aufrufer weiter (imFalleder main Methode an VM) public static void main (String [] args) { try { System.out.println ("1/0 = "+ divide(1,0)); } catch(ArithmeticException e) { System.out.println("I caught the Exception:" +e.getMessage()); } System.out.println("Life goes on!"); } } die aufrufende Methode kümmert sich um die Behandlung Verfassen eigener Exceptions Jede Exceptionklasse kann durch extends spezialisiert werden. public class MyException extends Exception { public MyException(String msg) { super(msg); } } Verfassen eigener Exceptions class TestKlasseMyException { public static void main (String [] args) { boolean test=false; //Auswurf von Exception try { try {//throw veranlasst das „Werfen“ einer Exception if (test) throw new MyException("Dies ist die Message von MyException"); throw new Exception(); } catch (MyException e) { System.out.println("MyException gefangen"); System.out.println(e.getMessage()); } } catch (Exception e2) { System.out.println("Exception gefangen"); System.out.println(e2.getMessage()); } } } Collections • Collections bieten ein Konzept, welches Objekte zu Gruppen zusammen fasst (z.B. eine Klasse (Gruppe von Studenten), ein Postfach (Gruppe von Emails) oder ein Telefonverzeichnis (Gruppe von Name- Telefonnummer- Paaren). • Mit einem Collection-Objekt können Instanzen beliebiger Klassen verwaltet werden. • Seit J2SE 5.0 gibt es Generics, welche im Zusammanhang mit Collections verwendet werden Einschub – Generics (Java 1.5) Beispiel : Es soll ein Container für eine einfache Zehl implementiert werden (Datentyp int): Äquivalent für Strings: class IntBox { private int val; void setValue( int val ) { this.val = val; } int getValue() { return val; } } class StringBox { private String val; void setValue(String val) { this.val = val; } String getValue() { return val; } } Könnte man so etwas nicht unabhängig vom Datentypen (generisch) programmieren ? Einschub – Generics (Java 1.5) In Java könnte eine Implementierung unserer StringBox mit Hilfe generischer Datentypen wie folgt aussehen: class Box< T > Anstelle des konkreten Typs String steht hier T (für Type). { private T val; void setValue( T { this.val = val; } T getValue() { return val; } } val ) Einschub – Generics (Java 1.5) Die so erstellte Klasse kann nun wie folgt benutzt werden: Box<String> stringBox = new Box<String>(); Box<Integer> intBox = new Box<Integer>(); Box<Point> pointBox = new Box<Point>(); stringBox.setValue(„Test“); String s= stringBox.getValue(); In Java können Generics nicht für primitive Datentypen verwendet werden. Allerdings können die Wrapper Klassen der primitiven Datentypen verwendet werden! Einschub – Generics (Java 1.5) Ebenso können Schablonen für Methoden verwendet werden. Dabei kann die Klasse („ganz normal“) ohne Schablone definiert werden. Dies gilt sowohl für Objektmethoden, als auch für Klassenmethoden (static). class Util { public static <T> T zufall( T m, T n ) { if(Math.random() > 0.5) return m; else return n; } } Aufruf: double zu=zufall(4.0,5.1); String zu=zufall("Hans","Peter"); int zu=zufall("Hans","Peter"); nicht möglich!!! Interface von Collections • boolean add(E o) Fügt das Objekt o hinzu und liefert true bzw. false, je nachdem, ob das Objekt erfolgreich hinzugefügt werden konnte. • void clear() Löscht alle Elemente im Container. • boolean contains(E o) Liefert true, wenn das Objekt o im Container enthalten ist. • boolean remove(E o) Liefert true, wenn das Objekt o im Container gelöscht werden konnte. • int size() Liefert die Anzahl der Elemente. • Iterator iterator() Liefert ein Iterator Objekt zum Zugriff auf die Elemente des Containers. E … Klasse für die die Collection erzeugt wurde. 8 Arten von Collections • Set (HashSet, TreeSet,...) • kann Elemente nicht doppelt enthalten • schnelle Suche • List (ArrayList, LinkedList, Vector, Stack,...) • kann Elemente doppelt enthalten • Elemente haben eine Reihenfolge • variable Länge, schnelles Einfügen und Löschen Arten von Collections Verwendung von List import java.util.*; class PointList { public static void main (String [] args) { LinkedList<Point> myPoints = new LinkedList<Point>(); myPoints.add(new Point(1.0,1.0)); System.out.println("Die Liste enthält " + myPoints.size()+" Punkt(e)!\n"); } } Iterator<Point> it = myPoints.iterator(); while(it.hasNext()) { Point b = it.next(); System.out.println("Point("+b.x+","+b.y+") "); } class Point { double x,y; Point(double xi, double yi) } { x=xi; y=yi; } Interface von Iterator Iteratoren (java Klasse Iterator ) werden verwendet um über eine Datenstruktur (zB Liste,Vector,…) zu iterieren: • boolean hasNext() Liefert true, wenn es weitere Elemente im Container gibt - bei false liefert der Aufruf von next eine Exception. • Object next() Liefert das nächste Element. • void remove() Löscht das aktuelle Element der Collection. Verwendung von Vector import java.util.*; class PointVector { public static void main (String [] args) { Vector<Point> myPoints = new Vector<Point>(); myPoints.add(new Point(1.0,1.0)); System.out.println("Die Liste enthält " + myPoints.size()+" Punkt(e)!\n"); for( int i=0; i<myPoints.size(); i++) { Point b = myPoints.elementAt(i); System.out.println("Point("+b.x+","+b.y+") "); } } } class Point { double x,y; Point(double xi, double yi) } { x=xi; y=yi; } Sonderfall: Map • Map (Hashtable, TreeMap,...) • schnelles Auffinden von Elementen über einen key • jedes Element muss einen eindeutigen key haben • Map hat ein anderes Interface als Collections: Object put(K key, Object V value); Object get(K key); Object remove(K key); int size(); boolean isEmpty(); void putAll(Map t); void clear(); public Set keySet(); /* Elemente wie durch ein K, V … Generics dadurch kann durch die Set iteriert werden! */ Verwendung von Maps import java.util.*; class PointMap { public static void main (String [] args) { TreeMap<String, Point> myPoints = new TreeMap<String, Point>(); myPoints.put("BUBU", new Point(1.0,1.0)); // 1. einen Iterator auf das keySet erzeugen Iterator<String> it // 2. Keys = myPoints.keySet().iterator(); durchgehen und Elemente while(it.hasNext()) { String aKey = it.next(); Point b = myPoints.get(aKey); System.out.println("Key: "+aKey } } } +" aus der Value: Map holen "+b); Weiterhin viel Spass mit Programmierung