Klassenvariablen - Mobile und Verteilte Systeme

Werbung
Javakurs für Anfänger
Einheit 09: Mehr zur Objektorientierung
Lorenz Schauer
Lehrstuhl für Mobile und Verteilte Systeme
Heutige Agenda
1. Teil: Weitere Aspekte der Objektorientierung
 Klassen Variablen
 Das Schlüsselwort static
 Beispiel: Instanzzähler
 Klassen Methoden
 Unveränderliche Attribute (Konstanten)
2. Teil: Vererbung
 Das Schlüsselwort extends
 Beispiel: Student und Person
 Subtyping und Type casting
Praxis:
 Klasse Student anpassen
 Übung mit Vererbung
 Weihnachtsbeispiel
Lernziele
 Unterschiede zwischen Instanz- und Klasseneigenschaften verstehen
 Einführung der Schlüsselwörter: static und final
 Konzept der Vererbung kennenlernen und verstehen
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
2
Klassenvariablen
So wie es Instanzvariablen gibt, die zu einer gewissen Instanz (Objekt) gehören und
deren Attribute speichern, so gibt es aus Klassenvariablen:
 Speichern Werte für eine ganze Klasse
 Sprich: Eine Änderung wirkt sich auf alle Objekte der Klasse aus!
 Beschreiben keine objektspezifischen Eigenschaften
 Werden auch als statische Attribute bezeichnet
 Eingeleitet mit dem Schlüsselwort static
 Bsp.: static int instances;
 Statische Attribute können, wie Instanzvariablen auch public, private, oder
protected sein
 Auf Klassenvariablen kann (je nach Sichtbarkeit) auch zugegriffen werden, selbst
wenn kein Objekt existiert
 Über: Klassenname.klassenvariable;
 Bsp.: Auto.instances;
 Zugriff über ein direktes Objekt ist auch möglich
 Über: objektname.klassenvariable;
 Bsp.: fiat.instances;
 Sollte allerdings vermieden werden
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
3
Anwendung für Klassenvariablen
Ein bekanntes Beispiel für die Anwendung von Klassenvariablen stellt ein
Instanzzähler dar:
// Beispiel für einen Instanzzähler über Klassenvariablen
public class Auto {
//Klassenvariable
public static int instances;
//Instanzvariablen
private String name;
private int preis;
//Konstruktor
public Auto(String name, int preis){
this.name = name;
this.preis = preis;
// Klassenvariable instances wird im Konstruktor erhöht
Auto.instances++;
}
}
//Weitere Methoden…
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
4
Anwendung für Klassenvariablen
Zugriff auf die Klassenvariable:
public class Autohaus {
public static void main(String[] args) {
System.out.println("Willkommen im Autohaus!");
System.out.println(" Es sind bereits "+Auto.instances+" Autos erzeugt worden!");
Auto fiatPunto = new Auto("fiatPunto", 9000);
Auto mercedes = new Auto("Mercedes",30000);
System.out.println("Es sind bereits "+Auto.instances+" Autos erzeugt worden!");
}
}
Ausgabe:
Willkommen im Autohaus!
Es sind bereits 0 Autos erzeugt worden!
Es sind bereits 2 Autos erzeugt worden!
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
5
Klassenmethoden
Neben den Klassenvariablen gibt es natürlich auch Klassenmethoden:
 Gehören zur Klasse und nicht zu den Objekten
 Können daher NUR auf Klassenvariablen arbeiten und NICHT auf Instanzvariablen
operieren!
 Beschreiben also kein Objektverhalten und manipulieren daher auch keine
Instanzvariablen
 Können nur Statische Methoden aufrufen
 Die Verwendung von this ist nicht möglich, da kein Objekt zugeordnet ist!
 Können direkt auf Klassen aufgerufen werden
 auch ohne, dass ein Objekt der Klasse existiert
 Beispiele:
 Main-Methode: public static void main(String[] args)
 Wird beim Programmstart aufgerufen, an dem noch keine Objekte existieren
 public static int getInstances() {return Auto.instances};
 Das Aufrufen über Objekte ist auch möglich, aber unerwünscht!
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
6
Anwendung für Klassenmethoden
Leichte Veränderung des Beispiels von vorher:
// Beispiel für einen Instanzzähler über private Klassenvariablen
public class Auto {
//Klassenvariable
private static int instances;
//Instanzvariablen
private String name;
private int preis;
//Konstruktor
public Auto(String name, int preis){
this.name = name;
this.preis = preis;
// Klassenvariable instances wird im Konstruktor erhöht
Auto.instances++;
}
//Weitere Methoden…
}
// Statischer Getter für statische Variable
public static int getInstances(){
return Auto.instances;
}
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
7
Anwendung für Klassenmethoden
Zugriff auf die Klassenvariable nun über den statischen Getter:
public class Autohaus {
public static void main(String[] args) {
System.out.println("Willkommen im Autohaus!");
System.out.println(" Es sind bereits "+Auto.getInstances()+" Autos erzeugt
worden!");
Auto fiatPunto = new Auto("fiatPunto", 9000);
Auto mercedes = new Auto("Mercedes",30000);
System.out.println("Es sind bereits "+Auto.getInstances()+" Autos erzeugt
worden!");
}
}
Ausgabe:
Willkommen im Autohaus!
Es sind bereits 0 Autos erzeugt worden!
Es sind bereits 2 Autos erzeugt worden!
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
8
Unveränderliche Attribute
(Konstanten)
Ein Anwendungsfall für statische Attribute sind Konstanten, die ihren Initialwert
nicht mehr verändern können.
 Beispiele für bekannte Konstanten:
 Math.PI, Math.E
 Wir können Konstanten, die eine Klasse anbieten soll selbst definieren:
 Mit dem Schlüsselwort final
 Sollten nach Konvention in GROßBUCHSTABEN deklariert werden
 Sollten public sein, um direkt von Außen darauf zugreifen zu können
// Beispiel für eigene Konstanten
// Konstanten benutzen
public class MeineKlasse{
public static final int MAX_VALUE = 10;
int max_wert = MeineKlasse.MAX_VALUE;
public static final double MEIN_WERT = 1.2;
public static final double PI = 3.14;
for(int i=0;i<MeineKlasse.MAX_VALUE;i++)
{
// Do something…
}
//Weitere Attribute und Methoden
}
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
9
Unveränderliche Attribute
Mit final lassen sich auch Instanzvariablen deklarieren, die nur einmal mit einem
Wert belegt werden dürfen, der sich danach nicht mehr verändern lässt
 Das kann sehr nützlich sein, wenn sich Initialbelegungen von Objekten nicht
mehr ändern dürfen
 Beispiel: Der Vorname eines Menschen ändert sich nicht mehr.
public class Mensch{
private final String vorname;
private String name;
// Einmalige Belegung durch Konstruktor erlaubt
public Mensch(String vorname, String name){
this.vorname = vorname;
this.name = name;
}
//Aber kein Setter für vorname erlaubt!
}
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
10
Kleine Programmieraufgabe
Nutzen Sie nun Ihre Klasse Student aus der letzten Stunde und verändern Sie die
Klasse wie folgt:
 Fügen Sie einen Instanzzähler ein, welcher es mittels einer Klassenvariablen
und einer entsprechenden Getter-Methode erlaubt, die Anzahl der erzeugten
Instanzen zu zählen und widerzugeben.
 Ändern Sie nun die Instanzvariable „matrikelnr“, so dass diese nur einmal mit
einem Wert belegt werden darf.
Prüfen Sie nun in Ihrem Programm (Main-Methode) den Instanzzähler und lassen
Sie sich die Anzahl der erzeugten Studenten ganz am Anfang und am Ende Ihres
Programms ausgeben.
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
11
Teil 2: Vererbung
Die Vererbung ist ein Kernprinzip der objektorientierten Programmierung
Motivation: Wiederverwendbarkeit von Klassen
 Neue Klassen müssen nicht immer komplett neu geschrieben werden!
 Oft reicht es aus, neue Klassen aus bestehenden abzuleiten => Vererbung
 Neue Klasse übernimmt die Eigenschaften und das Verhalten der alten Klasse
 Die neue Klasse wird auch als Sub-, Unter-, oder Kindklasse bezeichnet
 Die alte Klasse wird auch als Super-, Ober-, Basis-, Wurzel-, oder Vaterklasse
bezeichnet
 Die Unterklasse kann weitere Attribute
und Methoden definieren
Person
 Die Unterklasse kann Methoden der
Oberklasse überschreiben oder erweitern
 Vererbung stellt eine „is-a“ Beziehung dar.
 Ein Objekt der Unterklasse ist damit auch ein
Objekt der Oberklasse
 Bsp.: Ein Student ist auch eine Person
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
Student
12
Das Schlüsselwort extends
Eine Vererbung („is-a“-Beziehung) wird mit dem Schlüsselwort extends in der
Kopfzeile der Unterklasse nach dem Klassennamen eingeleitet
Beispiel: Person und Student:
 Person hat einen Namen, und einen Vornamen
 Person implementiert Getter- und Setter Methoden für name und vorname
 Student hat darüber hinaus noch eine Matrikelnummer
 Student implementiert nur noch die Getter- und Setter Methoden für
matrikelnummer
public class Student extends Person{
//Weitere Attribute und Methoden
}
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
13
Beispiel: Student extends Person
// Klasse Person (Oberklasse):
// Klasse Student (Unterklasse)
public class Person {
public class Student extends Person {
private String name;
private String vorname;
private int matrikelnr;
//Konstruktor
public Person(String name, String vorname) {
this.name = name;
this.vorname = vorname;
}
// Konstruktor
public Student(String name, String vorname,
int matrikelnr){
super(name,vorname);
this.matrikelnr = matrikelnr;
}
// Getter und Setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getVorname() {
return vorname;
}
public void setVorname(String vorname) {
this.vorname = vorname;
}
}
// Getter und Setter
public int getMatrikelnr() {
return matrikelnr;
}
public void setMatrikelnr(int matrikelnr) {
this.matrikelnr = matrikelnr;
}
17.12.2015
}
Javakurs 09: Mehr zur OO - Lorenz Schauer
14
Vererbung: Ein paar Regeln!
Der Zugriff auf Instanzvariablen der Oberklasse:
 Direkter Zugriff über das Schlüsselwort super
 Bsp.: super.InstanzVaraibleOberklasse
 Nur möglich, wenn InstanzVaraibleOberklasse public oder protected deklariert
wurde
 Private Instanzvariablen sind zwar vorhanden aber nicht sichtbar
=> Zugriff nur über Methoden möglich
Private Methoden der Oberklasse werden nicht vererbt!
Konstruktoren werden nicht vererbt!
 Der Konstruktor der Oberklasse kann jedoch im Konstruktor der Unterklasse
mit super aufgerufen werden!
 super(); // Konstruktor der Oberklasse ohne Parameter
 super(typ param1, typ param2,….) // Konstruktor der Oberklasse mit
Parameter
 Dieser Aufruf muss als erstes im Unterklassenkonstruktor definiert sein!
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
15
Verwendung der Klassen
Wir haben nun die beiden Klassen Person und Student definiert, wobei:
 Student von Person erbt
 Student ist also auch immer eine Person, aber nicht jede Person ist ein Student
 D.h.: Wir können den Studenten auch als eine Person im Code betrachten und
dementsprechend benutzen (Subtyping)
 Die Unterklasse ist ein Subtyp der Oberklasse
 Andersrum ist das nicht möglich!
// Beispiel: Benutzung der Klassen
Student studi1 = new Student("Matthias","Maier",9951);
Person person1 = new Student("Hansi","Hinterseer",1234);
//studi1 bietet alle Methoden eines Studenten:
String name1 = studi1.getName();
int matnr1 = studi1.getMatrikelnr();
//person1 bietet bisher nur die Methoden einer Person!
int matnr2 = person1.getMatrikelnr();
FEHLER: The method getMatrikelnr() is undefined for the type Person
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
16
Typkonvertierung
Wir wissen jedoch, dass die Person person1 eigtl. auch ein Student ist und alle
Informationen eines Studenten besitzt.
 In so einem Fall, können wir die Person person1 typkonvertieren, so dass
daraus ein Student wird:
 Bsp.: Student neuer_student = (Student) person1;
 Bei der Typkonvertierung (type cast) wird überprüft, ob die tatsächliche Klasse
von person1 eine Unterklasse von Person darstellt.
 Wenn ja: dann kein Problem
 Wenn nein: dann Laufzeitfehler: ClassCastException
 Mit dem Schlüsselwort instanceof lässt sich überprüfen, ob das Objekt
tatsächlich eine Instanz der angefragten Klasse ist
 Beispiel:
if(person1 instanceof Student){
// liefert true, falls person1 tatsächlich vom Typ Student ist
System.out.println("Passt");
}
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
17
Die Klasse Object
Implizit erben alle Klassen in Java von der Klasse Object
 Dadurch werden implizit bereits einige Methoden dieser Oberklasse
angeboten
 Beispiele:
 String toString(); // in einen String konvertieren
 boolean equals(Object other); // auf Gleichheit testen
 Object clone(); // Kopie des Objektes anlegen
 Dies kann man auch sehen, wenn man in einer eigenen Klasse bspw. im
Konstruktor this. eingibt
und sich von Eclipse
die Attribute und Methoden
anzeigen lässt
(Strg+Leertaste)
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
18
Programmieraufgabe zur Vererbung
Legen Sie ein neues Eclipse-Projekt „Uebung09“ an und bearbeiten Sie darin
folgende Aufgabe zur Vererbung in Java:
Der Weihnachtsmann braucht für seine Fahrt auf dem Schlitten insgesamt 4
Rentiere, damit er vorwärts kommt. Da es aber im Wald dunkel ist, muss ein
Rentier „Rudolph“ sein, der eine leuchtende Nase hat.
 Schreiben Sie eine Klasse „Weihnachtsmann“ mit folgenden Eigenschaften:
 Besitzt unveränderbaren Namen „Santa“
 Besitzt eine private Liste vom Typ „Rentier“, welche die Rentiere speichert, die am
Schlitten angebunden sind
 Außerdem besitzt er eine Methode, um Rentiere hinzuzufügen und
 eine Methode, um Rentiere zu entfernen
 Die Klasse hat noch eine Getter-Methode für die Rentierliste
 Außerdem gibt es eine Methode void losfahren(), damit der Weihnachtsmann
losfahren kann.
 Die Methode gibt aber erst „Santa faehrt los “ aus, wenn mindestens 3 normale
Rentiere und ein „Rudolph“ Rentier am Schlitten angebunden sind.
 Ist das nicht der Fall, passiert beim Aufruf der Methode nichts.
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
19
Programmieraufgabe zur Vererbung
Implementieren Sie eine Klasse Rentier mit folgenden Eigenschaften:
 Jedes Rentier bekommt beim Erzeugen eine eindeutige ID (int), die nach der
Erzeugung nicht mehr veränderbar ist!
 Außerdem hat jedes Rentier eine Größe (double), welche beim Erzeugen ebenfalls
angegeben werden soll!
 Als Methoden stellt ein Rentier die beiden Getter seiner Instanzvariablen zur
Verfügung, nämlich für int id und double groesse
Implementieren Sie nun eine Klasse RentierRudolph, welche logischerweise auch ein
Rentier ist (erbt von der Klasse Rentier)
 Rudolph hat den festen Namen „Rudolph“ und einen boolschen Wert leuchten, der
angibt, ob er gerade leuchtet
 Die Klasse soll über 2 Methoden void leuchten() und void nichtLeuchten()
den booleschen Wert entsprechend setzen können.
Schreiben Sie nun eine Anwendung und erzeugen Sie sich einen Weihnachtsmann, der
verschiedene Rentiere hinzufügt. Versuchen Sie dessen Methode losfahren()
auszuführen. Zur Erinnerung: diese Methode sollte nur „Santa faehrt los“ ausgeben,
wenn mindestens 3 normale Rentiere und ein „Rudolph“ am Schlitten angebunden
sind.
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
20
Frohe Weihnachten in Java
Ein kleines Java Beispiel um zu sagen:
Frohe Weihnachten und an
guadn Rutsch ins neue Jahr!
17.12.2015
Javakurs 09: Mehr zur OO - Lorenz Schauer
21
Herunterladen