Kapitel 8 Programmierkurs Birgit Engels Anna Schulze Zentrum für Angewandte Informatik Köln Objektorientierte Programmierung Methoden Überladen von Methoden Der this-zeiger Konstruktoren Vererbung WS 07/08 1/ 24 2/ 24 Methoden 8.1 Methoden Eine Methode stellt eine Anweisungsliste dar Sie wird innerhalb einer Klassendefinition angelegt Sie hat Zugriff auf alle Variablen des Objekts Globale Funktionen, die vollkommen unabhängig von einem Objekt oder einer Klasse existieren, gibt es ebensowenig wie globale Variablen Später: Klassenvariablen und -methoden, die nicht an eine konkrete Instanz gebunden sind 3/ 24 4/ 24
Rückgabewert von Methoden Methoden mit Parametern public int alter() return 2007 - erstzulassung; Jede Methode ist typisiert der Typ bestimmt den Typ des Rückgabewerts Typ kann primitiver Typ, Objekttyp oder vom Typ void sein Methoden vom Typ void haben keinen Rückgabewert Rückgabewert wird mit return-anweisung zurück gegeben: return Ausdruck; return-anweisung führt zum Beenden der Methode public void printalter(string text, int wieoft) while (wieoft-- > 0) System.out.println(text + alter()); Parameter werden durch Kommata getrennt innerhalb der Klammern der Methode angegeben Jeder Parameter besteht aus einem Typnamen und dem Namen des Parameters 5/ 24 6/ 24 Methoden mit Parametern Alle Parameter werden per call by value übergeben, d.h. Beim Aufruf der Methode wird aktuelle Wert der Variable in die Parametervariable kopiert und an die Methode übergeben Veränderungen der Parametervariablen innerhalb der Methode bleiben lokal Im Beispiel wird wieoft nur innerhalb der Methode verändert, der Aufrufer bemerkt es nicht Wie oft wird das Alter von meinkombi in folgendem Beispiel ausgegeben?... int a = 3; meinkombi.printalter( BMW,a); meinkombi.printalter( Mercedes,a); meinkombi.printalter( Porsche,a);... Call by value bei Objektvariablen Objektvariablen sind Referenzen Bei der Übergabe an eine Methode werden sie per Wert übergeben, d.h. aber der Wert der Referenz wird übergeben Veränderung an dem Objekt sind somit auch für den Aufrufer der Methode sichtbar call by value für Objektvariablen entspricht call by reference WICHTIG: Die Übergabe von Objekten an Methoden hat damit zwei wichtige Konsequenzen: Die Methode erhält keine Kopie, sondern arbeitet mit dem Originalobjekt. Sollen Objekte kopiert werden, so muss dies explizit durch Aufruf der Methode clone der Klasse Object erfolgen 7/ 24 8/ 24
Überladen von Methoden 8.2 Überladen von Methoden Definiere innerhalb einer Klasse zwei unterschiedliche Methoden mit demselben Namen Compiler arbeitet mit Signatur einer Methode, die sich aus dem Namen und über die Reihenfolge und Typen der Parameter zusammensetzt. Die Methoden müssen sich in dieser Signatur unterscheiden, d.h. in der Reihenfolge und/oder Typisierung der Parameter 9/ 24 10/ 24 Überladen von Methoden public class Auto public String name; public int erstzulassung; public int alter() return 2007 - erstzulassung; public int alter(string titel) int alter = alter(); System.out.println(titel+alter); return alter; 8.3 Der this-zeiger Beachte: alter wird in drei verschiedenen Bedeutungen verwendet. 11/ 24 12/ 24
Der this-zeiger public class ThisExample public int x=5; public int y=10; public void xplusy() int y=1; System.out.println(x+this.y); System.out.println(x+y); public static void main(string[] args) ThisExample test = new ThisExample(); test.xplusy(); 8.4 Konstruktoren Methoden dürfen auf die Variablen ihrer Klasse ohne Punktnotation zugreifen. Compiler interpretiert alle nicht lokalen Variablen x ohne Punktnotation als this.x. Was ist die Ausgabe des Programms? Ausgabe des Programms sind die Zahlen 15 und 6. Konstruktoren Konstruktoren sind Methoden, die bei der Initialisierung eines Objekts aufgerufen werden Ein Konstruktor erhält den Namen der Klasse und hat keine Rückgabewert 13/ 24 Überladen von Konstruktoren public Auto(String name) this.name = name; 14/ 24 public class Auto public String name; public int erstzulassung; public Auto(String name) this.name = name; Auto dasauto = new Auto( Porsche 911 ); 15/ 24 public Auto(String name, int erstzulassung) this(name); this.erstzulassung = erstzulassung; Wird ein Konstruktor in einer Methode derselben Klasse aufgerufen, muss dies als erste Anweisung innerhalb der Methode geschehen Sobald ein eigener Konstruktor definiert ist, kann der default-konstruktor nicht mehr aufgerufen werden 16/ 24
8.5 Vererbung Vererbung Unter Vererbung versteht man die Möglichkeit Eigenschaften vorhandener Klassen auf neue Klassen zu übertragen Mit dem Schlüsselwort extends wird die Basisklasse angegeben Hierdurch erbt die abgeleitete Klasse alle Variablen und Methoden der Basisklasse Besitzt eine Klasse das Attribut final, ist es nicht erlaubt, eine neue Klasse aus ihr abzuleiten class Cabrio extends Auto int vdauer; Die Klasse Cabrio unterscheidet sich von der Klasse Auto nur dadurch, dass sie zusätzlich die Zeit speichert, die zum Öffnen der Verdecks benötigt wird. 17/ 24 18/ 24 Zugriff auf vererbte Eigenschaften Verschachtelte Vererbung Die Vererbung kann beliebig tief geschachtelt werden Cabrio kfz1 = new Cabrio(); kfz1.name = MX5 ; kfz1.erzulassung = 1995; System.out.println( Alter = +kfz1.alter()); Es kann auf sämtliche Variablen und Methoden der Basisklasse zugegriffen werden class ZweisitzerCabrio extends Cabrio boolean notsitze; ZweisitzerCabrio kfz1 = new ZweisitzerCabrio(); kfz1.name = 911-T ; Es kann auf sämtliche Variablen und Methoden der Basisklasse und auch ihrer geerbten Variablen und Methoden zugegriffen werden 19/ 24 20/ 24
Methodenüberlagerung Dynamische Methodensuche Geerbte Methoden können neu definiert werden (überlagert werden) Es wird immer die überlagernde Version verwendet class ZweisitzerCabrio extends Cabrio boolean notsitze; public int alter() return 12 * (2007 - erstzulassung); Nicht immer kann bereits der Compiler entscheiden, welche Variante einer überlagerten Methode er aufrufen soll Ein Cabrio-Objekt kann einer Variablen vom Typ Auto zugewiesen werden D.h. die Variable vom Typ Auto kann während ihrer Lebensdauer Objekte verschiedenen Typs enthalten (z.b. vom Typ Auto, Cabrio, ZweisitzerCabrio Compiler muss Code generieren, der zur Laufzeit entscheidet welche überlagerte Methode er benutzt Das wird als dynamisches Binden bezeichnet Dies verursacht erheblichen Aufwand an Laufzeit (im Unterschied zu C/C++) 21/ 24 22/ 24 Verhinderung Dynamischer Methodensuche Aufrufen einer verdeckten Methode Um zu verhindern, dass eine Methode dynamisch interpretiert wird, können folgende Attribute benutzt werden: Methoden vom Typ private sind in abgeleiteten Klassen nicht sichtbar und können daher nicht überlagert werden. Bei Methoden vom Typ final deklariert der Anwender explizit, dass sie nicht überlagert werden sollen. Auch bei static-methoden, die ja unabhängig von einer Instanz existieren, besteht das Problem nicht Wird eine Methode x in einer abgeleiteten Klasse überlagert, wird die ursprüngliche Methode x verdeckt Mit super.x() kann auf die verdeckte Methode zugegriffen werden super.super.x() ist nicht erlaubt Innerhalb des Konstruktors wird mit dem Aufruf super() der Konstruktor der Basisklasse aufgerufen Hierbei wird super wie eine normale Methode verwendet und kann mit oder ohne Parameter aufgerufen werden 23/ 24 24/ 24