Packages - Universität zu Lübeck

Werbung
Programmierkurs Java
Konstruktor, Statische Methoden
Packages
Prof. Dr. Stefan Fischer
Institut für Telematik, Universität zu Lübeck
http://www.itm.uni-luebeck.de/people/fischer
Initialisierung von Datenstrukturen
• Weiteres Problem prozeduraler
Programmierung
– Initialisierung von Datenstrukturen
– Unklare Zuständigkeit
• Häufig nur durch Dokumentation
ersichtlich
– Beispiel: „Beim Verwenden der
Datenstruktur Lampe muss zu Beginn die
Funktion init_helligkeit(Lampe l);
aufgerufen werden“
– Wird häufig vergessen
– Führt potenziell zu undefiniertem bzw.
ungewolltem Verhalten
#2
Wichtiges Prinzip: Konstruktion
• Instanzen können bei der Erzeugung automatisch
initialisiert werden
– Aufruf von speziellen Methoden durch Java
– Geschieht bei der Erzeugung mittels new
• Diese speziellen Methoden heißen „Konstruktoren“
– Werden automatisch bei der Erzeugung (durch new) aufgerufen
– Bringen Instanzen in einen „sicheren“ initialen Zustand
• In anderen Programmiersprachen gibt es auch Destruktoren
– z.B. Freigeben von Speicher, etc.
#3
Umsetzung in Java
• Konstruktoren: Methoden mit speziellem Namen und Rückgabetyp
– Name der Methode: Klassenname
– Rückgabetyp: Keiner, nicht einmal void
– Konstruktor sollte alle Attribute initialisieren (guter Stil)
• Syntax: Klassenname(Typ1 Name1, Typ2 Name2, …) {…}
– Beispiel: Punkt(double x, double y) {...}
• Eine Klasse kann mehrere Konstruktoren haben
– Gleiches Prinzip wie Überladen von Methoden
• Ein Konstruktor kann als erstes anderen Konstruktor aufrufen
– Syntax: this(...parameter...);
#4
Beispiel
•
Erzeugung von zwei
Punkt-Instanzen in
main
•
Zeile 19
–
–
–
•
Kein Parameter an den
Konstruktor
Aufruf des parameterlosen Konstruktors aus
Zeile 6
Dieser ruft Konstruktor
in Zeile 10 auf
Verwendung von „this“
Zeile 20
–
–
Zwei doubleParameter
Aufruf des
Konstruktors in Zeile
10
#5
Statische Methoden und Attribute
Statische Methoden
• Methoden verändern den Zustand einer Objektinstanz
– bzw. liefern Informationen über deren Zustand
• Manchmal praktisch, dieses Modell zu durchbrechen
– Main-Methode (Programmstart: keine Instanzen)
– Mathematische Funktionen (Wurzel, Sinus, Kosinus, etc.)
• Primitive Datentypen sind keine Objekte  1.sinus() funktioniert nicht
• new Sinus(1).getWert()  zu großer Overhead
• Beispiele http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html
#7
Statische Methoden und Attribute
• Schlüsselwort static (unabhängig von Klasseninstanzen)
– Es gibt keine „this“-Referenz (keine Instanz verfügbar)
– Statische Elemente können nur andere statische Elemente verwenden
– Aufruf anderer statischer Methoden oder Verwenden statischer Variablen
• Statische Methoden
– Definition: static void statischeMethode(...) {...}
– Verwendung: Klassenname.methodenname(Parameter)
• Statische Attribute
– Definition: static int statischesAttribut;
– Verwendung: Klassenname.attributname;
#8
Beispiel: Standardausgabe
• System.out.println(“Hallo“);
Klasse
„System“
Statisches
Attribut „out“
Teil der Java
KlassenBibliothek
Instanz der
Klasse
PrintStream
Methode
„println“
Implementiert
in PrintStream
#9
Beispiel: Instanzzähler
#10
Beispiel statisch/nicht-statisch
#11
Packages
Probleme großer Projekte
• Programme können aus vielen Klassen bestehen
– Verschiedene logische Funktionskomponenten
– Müssen nicht von einem Hersteller bzw.
Programmierer stammen
– Normalerweise besteht ein Programm aus Teilen vieler
Programmierer (externe Bibliotheken, Teams, ...)
• Probleme
– Klassennamen doppelt vergeben  Eindeutigkeit
– Unklare Zuordnung Funktionseinheit  Klasse
#13
Beispiel: Zwei „Punkt“-Klassen
#14
Beispiel: Zwei „Punkt“-Klassen
• Wie unterscheidet man die beiden Klassen im gleichen Programm?
• Eine Möglichkeit: umbenennen
– „PunktRGB“ und „PunktKoordinate“
– Macht Programme oft schlechter lesbar (lange Namen)
• Beispiele (Windows API, Ungarische Notation)
– RtlWriteDecodedUcsDataIntoSmartLBlobUcsWritingContext
– ConvertSecurityDescriptorToStringSecurityDescriptor
– EapHostPeerQueryUIBlobFromInteractiveUIInputFields
– AccessCheckByTypeResultListAndAuditAlarmByHandle
– SetupRemoveInstallSectionFromDiskSpaceList
#15
Namensräume
• Alternative zu langen Namen
• Eingruppieren von Klassen in verschiedene Namensräumen
– Unterscheidung von Klassen durch Angabe des Namensraums
– Beispiel: Punkt aus „Farbe“ vs. Punkt aus „Mathe“
• Namensräume in Java: sog. „packages“
Namensraum „Farbe“
Namensraum „Mathe“
Punkt
Punkt
Attribute:
- int rot;
- int gruen;
- int blau
Attribute:
- double x;
- double y;
Methoden:
Methoden:
- void setze(double x, double y);
- void verschiebe(double dx, double dy);
- void rotiere(double radians);
#16
Packages
• Es ist üblich, Klassen in Packages zu gruppieren
– Bessere Übersichtlichkeit
– Vorbeugung von Namenskonflikten
– Zusammengehörige Klassen kennzeichnen
• Analogie
– Klassennamen sind vergleichbar mit einem Vornamen
– Package-Name entspräche dann dem Familiennamen
• Package-Namen: Gleiche Einschränkungen wie Identifier
– z.B. kein „-“ erlaubt
– Konvention: Kleinschreibung (also „mathe“ statt „Mathe“)
#17
Packages: Beispiel
#18
Nested Namespaces
• Namespaces können auch ineinander geschachtelt werden
• Beispiel
–
–
–
–
Punkt in „Farbe“
Punkt in „rgb“ in „Farbe“
Punkt in „version1“ in „rgb“ in „Farbe“
Punkt in „cmyk“ in „Farbe“
Namensraum „Farbe“
Punkt
Namensraum „rgb“
Namensraum „cmyk“
Namensraum „version1“
Punkt
Punkt
Punkt
#19
Nested Namespaces: Java Beispiel
• Einzelne Bestandteile werden durch „.“ getrennt
• Beginnt bei der höchsten Hierarchiestufe
– Ähnlich wie im Dateisystem
– Packages müssen immer „absolut“ angegeben werden
(d.h. alle Namensteile müssen vorhanden sein)
#20
Packages: Namenswahl
•
Sinnvoll: Weltweit eindeutige Namen
– Üblich sind Internet-Domainnamen in umgekehrter Schreibweise
– Damit man Klassen aus verschiedenen Quellen ohne Namenskonflikte nutzen kann
•
Beispiel: Klassen aus dem ITM
– Domainname: itm.uni-luebeck.de
– Package de.uni_luebeck.itm (Verwendung von „_“ statt „-“)
– Sinnvoll: Anhängen des Projektnames (z.B. „programmieren.ws1213.uebung1.aufgabe2“)
– Gesamt: de.uni_luebeck.itm.programmieren.ws1213.uebung1.aufgabe2;
#21
Packages: Verwendung
• Zwei Varianten zur Verwendung von Klassen aus anderen Packages
• Angabe des voll-qualifizierten Namens (Klasse + Package)
– package test;
...
farbe.rgb.Punkt p = new farbe.rgb.Punkt();
• Importieren bestimmter Klassennamen
– Um die Angabe des voll-qualifizierten zu ersparen (Lesbarkeit)
– Schlüsselwort: import
– import farbe.rgb.Punkt;
...
Punkt p = new Punkt();
#22
Packages: Verwendung
• Kann natürlich auch gemischt verwendet werden
• Beispiel
– package test;
import farbe.rgb.Punkt;
...
Punkt p1 = new Punkt();
farbe.cmyk.Punkt p2 = new farbe.cmyk.Punkt();
farbe.rgb.version1.Punkt p3 =
new farbe.rgb.version1.Punkt();
• Es sind nach wie vor verschiedene Klassen
– Punkt p1 = new farbe.cmyk.Punkt(); //Fehler!!!
#23
Packages: Verwendung
•
Alternative Variante von import
– Importieren ganzer Packages (z.B. import java.util.*;)
– Alle Namen aus java.util können ohne Angabe des Packages verwendet werden
– Gilt nicht für eventuelle Unterpackages von java.util
•
Wo/wann benutzt man Packages?
– In allen größeren Java-Projekten
– Intensiv in der Java-API: http://download.oracle.com/javase/7/docs/api/
(hier sollten sich Java-Programmierer gut auskennen)
•
In Java ist java.lang.*; implizit immer importiert
– Daher kann man auch System.out.println(...); statt
java.lang.System.out.println(...); schreiben
#24
Klassen ohne Package
• In welchem Package waren eigentlich unsere
bisherigen Klassen?
• Kein Package: sog. default Package
– Quasi ein Package ohne Namen
– Daher liegen diese auch im Wurzelverzeichnis des
Projekts
– Sollte man nur bei ganz kleinen Projekten nutzen
#25
Herunterladen