Fachhochschule Südwestfalen Peter Ziesche E-Mail: [email protected] Einführung in die Programmierung Sommersemester 2005 – 2. Semester Das Beispiel aus der Übung Eine wichtige Aufgabe bei der Entwicklung einer Anwendung ist die Ermittlung der relevanten Daten. Eine Anwendung bildet Entitäten (z.B. Personen, Autos) der realen Welt in Software ab. Diese Entitäten haben in der Realität praktisch unendlich viele Eigenschaften. Für die Anwendung ist immer nur ein kleiner Teil dieser Eigenschaften wichtig. Für eine Kundenverwaltung sind z.B. folgende Eigenschaften wichtig: Name, Vorname, Adresse, Kunden-Nummer, Typ (Privat- oder Geschäftskunde) Ein konkreter Kunde, z.B. Tina Meier, wird in Java durch ein Objekt dargestellt. Für jeden Kunden wird existiert ein separates Objekt. Das Objekt repräsentiert den Kunden und speichert die relevanten Eigenschaften. Alle Kunden haben, obwohl es sich um individuelle Menschen handelt, aus Sicht der Kundenverwaltung die gleichen Eigenschaften. Um nicht für jeden Kunden getrennt diese Eigenschaften beschreiben zu müssen, entwickelt man eine Schablone, in der die gemeinsamen Eigenschaften aller Kunden beschrieben sind. Diese Schablone wird in Java Klasse genannt. Alle Kunden-Objekte werden mit Hilfe der einheitlichen Schablone (Klasse) erzeugt, haben also alle die gleichen Eigenschaften. Jedes Kunden-Objekt hat aber individuelle Werte für die einzelnen Eigenschaften. Jeder Kunde hat einen Namen, aber dieser Name ist bei jedem Kunden anders. public class Kunde { String Name; String Vorname; String Adresse; int KundenNr; boolean IstFirmenkunde; } Anstelle von „Eigenschaft“ werden auch die Begriffe „Attribut“, „Merkmal“ oder „Feld“ (Javaspezifisch) verwendet. Die entsprechenden englischen Begriffe lauten „property“, „attribute“, „feature“ und „field“. Eigenschaften sind in Java Variablen, die zu einer Klasse gehören. Wie bei Variablen üblich, haben sie immer einen Typ. Ergibt an, welche Werte in der Eigenschaft gespeichert werden können. Von der Klasse Kunde können Objekte erzeugt und die Eigenschaften mit Werten gefüllt werden. Anschließend können die Kundendaten auf dem Bildschirm angezeigt werden. Dies erfolgt am besten in der main()-Methode, mit der jedes Java-Programm startet. Die main()Methode kann in die Klasse Kunde geschrieben werden oder alternativ in einer anderen Klasse stehen. public static void main( String[] args ) { //erstes Kundenobjekt anlegen Kunde kunde1 = new Kunde(); kunde1.Name = "Meier"; kunde1.Vorname = "Tina"; kunde1.Adresse = "Markstr."; kunde1.KundenNr = 312416; kunde1.IstFirmenkunde = false; //zweites Kundenobjekt anlegen Kunde kunde2 = new Kunde(); kunde2.Name = "Schmidt"; kunde2.Vorname = "Thomas"; kunde2.Adresse = "Wittener Str."; kunde2.KundenNr = 468256; kunde2.IstFirmenkunde = true; //Kundendaten ausgeben System.out.println( "Kunde: " + kunde1.Vorname + " " + kunde1.Name ); System.out.println( "Kunde: " + kunde2.Vorname + " " + kunde2.Name ); } Der lesende oder schreibende Zugriff auf die Eigenschaften eines Objekts erfolgt in Java und in vielen anderen objektorientierten Programmiersprachen über die Punkt-Notation: Objekt.Eigenschaft = Wert (schreibender Zugriff) Objekt.Eigenschaft (lesender Zugriff) Durch die Ausführung der main()-Methode werden im Arbeitsspeicher des Rechners Objekte angelegt. Die prinzipielle Struktur sieht so aus (die Namen der Objekte sind willkürlich gewählt): :Kunde :Kunde Name = "Meier" Vorname = "Tina" Adresse = "Markstr." KundenNr = 312416 Ist Firmenkunde = false Name = "Schmidt" Vorname = "Thomas" Adresse = "Wittener Str." KundenNr = 468256 Ist Firmenkunde = true kunde1 kunde2 Die beiden lokalen Variablen kunde1 und kunde2 haben als Typ die Klasse Kunde. Sie sind Referenz-Variablen, d.h. sie enthalten keine Werte, sondern den Speicherort eines Objekts. Alle Variablen, die als Typ eine Klasse haben, sind in Java Referenz-Variablen. Über sie kann mit der Punkt-Notation auf die Eigenschaften des referenzierten Objekts zugegriffen werden. Eine Variable, deren Typ keine Klasse ist, z.B. int, heißt einfache Variable oder Wert-Variable. Sie speichert direkt einen Wert. Da die Eigenschaften einer Klasse Variablen sind, gilt auch für sie die Unterteilung in einfache Eigenschaften und Referenz-Eigenschaften. Neben Eigenschaften können Klassen auch Methoden enthalten. Für die Klasse Kunde soll eine Methode erhalten, die die Anschrift des Kunden zurückliefert. String getAnschrift() { String anschrift; if( IstFirmenkunde ) { anschrift = „Firma\n“; } else { anschrift = "Herr/Frau"; } anschrift = anschrift + Vorname + „ „ + Name + „\n“; anschrift = anschrift + Adresse; return anschrift; } Die Methode hat den Typ String (Zeichenkette), d.h. sie muss als Ergebnis einen String zurückliefern. Dazu wertet sie zunächst die Eigenschaft IstFirmenkunde aus und definiert die Anschrift unterschiedlich für Firmen- und Privatkunden. Die anderen Eigenschaften für die Anschrift werden an die Anschrift angehängt (Fachausdruck: konkateniert). Das Steuerzeichen \n innerhalb einer Zeichenkette steht für einen Zeilenumbruch. Die Methode getAnschrift() kann, da sie zur Klasse Kunde gehört, direkt auf die Eigenschaften der Klasse zugreifen. Sie können wie lokale Variablen benutzt werden. Das Lesen und Schreiben der Eigenschaften erfolgt unabhängig von einem konkreten Objekt. Erst beim Aufruf der Methode wird festgelegt, von welchem Objekt die Eigenschaften verwendet werden sollen, also von welchem Kunden die Anschrift ausgegeben werden soll. System.out.println( "Anschrift: " + kunde1.getAnschrift() ); System.out.println( "Anschrift: " + kunde2.getAnschrift() ); Die Anwendung zur Kundenverwaltung soll nun so erweitert werden, dass auch Produkte und Verkäufe verwaltet werden können. Dazu werden zwei weitere Klassen geschrieben. public class Produkt { int ProduktNr; String Bezeichnung; } public class Verkauf { Kunde Kaeufer; Produkt Artikel; int Anzahl; } Die Klasse Produkt hat zwei Eigenschaften, beide haben einfache Typen (String und int). Ein Verkauf speichert neben der Anzahl der verkauften Artikel die Information, welcher Kunde welches Produkt gekauft hat. Die beiden Eigenschaften Kaeufer und Artikel haben als Typen die Klasse Kunde bzw. die Klasse Produkt. Sie sind Referenz-Eigenschaften. Als Beispiel sollen ein Auto als Produkt und zwei Verkäufe erzeugt werden. Die Kunden Tina Meier soll ein Auto kaufen, der Kunde Thomas Schmidt fünf Autos. Der folgende Code gehört in die main()-Methode. Produkt auto = new Produkt(); auto.ProduktNr = 3579; auto.Bezeichnung = "Auto"; Verkauf v1 = new Verkauf(); v1.Kaeufer = kunde1; v1.Artikel = auto; v1.Anzahl = 1; Verkauf v2 = new Verkauf(); v2.Kaeufer = kunde2; v2.Artikel = auto; v2.Anzahl = 5; Nach der Ausführung dieser Anweisungen ergibt sich folgendes Bild im Speicher: :Kunde :Kunde Name = "Meier" Vorname = "Tina" Adresse = "Markstr." KundenNr = 312416 Ist Firmenkunde = false Name = "Schmidt" Vorname = "Thomas" Adresse = "Wittener Str." KundenNr = 468256 Ist Firmenkunde = true kunde1 kunde2 v2 auto :Verkauf v1 Kaeufer = Artikel = Anzahl = 1 :Verkauf :Produkt ProduktNr = 3579 Bezeichnung = "Auto" Kaeufer = Artikel = Anzahl = 1 Auf ein Objekt können mehrere Referenz-Variablen gleichzeitig zeigen. Auf das ProduktObjekt zeigen z.B. die lokale Variable auto und die beiden Eigenschaften v1.Artikel und v2.Artikel. Alle Referenzen sind gleichwertig. Das Abfragen oder Verändern einer Eigenschaft kann über irgendeine der Referenzen erfolgen. Um die Bezeichnung des Produkts auszugeben, sind die drei folgenden Zeilen gleichermaßen geeignet: System.out.println( auto.Bezeichnung ); System.out.println( v1.Artikel.Bezeichnung ); System.out.println( v2.Artikel.Bezeichnung ); Wie man sieht, lässt sich der Zugriff auf Eigenschaften mit der Punkt-Notation beliebig oft hintereinander ausführen. Die Variable v1 zeigt auf ein Objekt. Über die Punkt-Notation wird auf die Eigenscahft Artikel zugegriffen. Dieses ist eine Referenz auf ein Produkt-Objekt. Also kann durch nochmalige Anwendung der Punkt-Notation auf die Eigenschaften des Produkts zugegriffen werden. Das Objekt und seine Eigenschaften sind nur einmal im Speicher vorhanden. Eine Veränderung von Eigenschaften über eine Referenz ist also anschließend von allen Referenzen aus sichtbar. Die folgenden Zeilen geben einmal Auto und einmal Porsche auf dem Bildschirm aus: System.out.println( v2.Artikel.Bezeichnung ); v1.Artikel.Bezeichnung = "Porsche"; System.out.println( auto.Bezeichnung ); Manipulation von Referenzen Referenz-Eigenschaften kann ein neuer Wert zugewiesen werden. Sie zeigen dann auf ein anderes Objekt. Der zweite Verkauf soll z.B. statt von Tina Meier von Thomas Schmidt getätigt werden. In der main()-Methode kann man einfach schreiben: v1.Kaeufer = kunde2; Dadurch werden die beiden Objekte nicht verändert. Es wird nur die Referenz-Eigenschaft Kaeufer verändert. Sie zeigt auf ein anderes Objekt. Das Speicherbild sieht danach wie folgt aus: :Kunde :Kunde Name = "Meier" Vorname = "Tina" Adresse = "Markstr." KundenNr = 312416 Ist Firmenkunde = false Name = "Schmidt" Vorname = "Thomas" Adresse = "Wittener Str." KundenNr = 468256 Ist Firmenkunde = true kunde1 kunde2 v2 auto :Verkauf v1 Kaeufer = Artikel = Anzahl = 1 :Verkauf :Produkt ProduktNr = 3579 Bezeichnung = "Porsche" Kaeufer = Artikel = Anzahl = 1