unterschiedliche Leuchtmittel an einem Wagenrad

Kapselung und Konstruktoren



Quellen: E. Fuchs, "Java 9 Grundlagen Programmierung", Herdt Verlag, 2017

In der objektorientierten Programmierung begrenzt man normalerweise den Zugriff von Objekteigenschaften (Attribute) auf die Methoden einer Klasse. Man spricht von Kapselung. Gleichzeitig möchte man direkt beim Erzeugen eines neuen Objektes dessen Attribute setzen. Dies ist möglich mit dem sogenannten Konstruktor.

In diesem Artikel lernst Du set- und get-Methoden, die Bedeutung der Modifier, das UML-Klassendiagramm und Konstruktoren kennen.

Kapselung sowie set- und get-Methoden Abschirmen von Attributen

Zeichnung zweier unterschiedlicher Schafe
In der Klasse Leuchtmittel werden folgende Eigenschaften für die Leuchtmittel definiert: Leistungsaufnahme P in W (Watt), Spannung U in V (Volt) und Strom I in A (Ampere). Die Leistung kann mit P = U ⋅ I berechnet werden.

public class Leuchtmittel{
  public double spannung;
  public double strom;
  public double leistung;
}

Probleme bei der Objekterzeugung in der Klasse Lampe

Eine Wagenradlampe der Klasse Lampe besteht aus Objekten der Leuchtmittel. Wir erstellen nun ein Objekt:

public class Lampe {
  public static void main(String[] args) {
    Leuchtmittel l1 = new Leuchtmittel();  //Objekterzeugung L1 
    l1.spannung = 230.0;
    l1.strom = -0.1;     //Problem: negativer Wert
    l1.leistung = 60.0;  //Problem: P ist von U und I abhängig
  } 
}	

Folgende Probleme treten auf:

  1. Der Benutzer der Klasse Lampe kann die Leistung unabhängig von Spannung und Strom setzen. Die Leistung eines Leuchtmittels ist aber von dessen Spannung und Stromaufnahme abhängig. So können Leuchtmittel entstehen, die es in der realen Welt gar nicht gibt.
  2. Der Benutzer kann negative Maße setzen, welche es in der realen Welt nicht gibt. Auch eine Validierung gibt es nicht.

Lösung mit Kapselung und set-get-Methoden in der Klasse Leuchtmittel

Wir ersetzen den Modifier der Attribute in der Klasse Leuchtmittel durch private. Dadurch wird der Attributzugriff auf die Klasse Leuchtmittel beschränkt. Diesen Vorgang nennt man Kapselung. Man schirmt die Attribute vom Zugriff aus anderen Klassen ab.

Um nun die Werte noch ändern zu können benötigt man die sogenannten set-Methoden; für den Wertzugriff die get-Methoden.Der indirekte Zugriff auf die Leuchtmittelattribute erfolgt aus der Klasse Lampe:

public class Lampe {
  public static void main(String[] args) {
    Leuchtmittel l1 = new Leuchtmittel();  //Objekterzeugung l1 
    l1.setSpannung(230.0);
    l1.setStrom(0.1);    

    System.out.println(l1.getLeistung());
  } 
}	
public class Leuchtmittel{
  private double spannung = 0;
  private double strom = 0;
  private double leistung = 0;

  public void setSpannung(double u){
    if(u<=0)  System.out.println("Wert fehlerhaft");
    this.spannung = u;
    this.leistung = u * this.strom;    
  }
  
  public void setStrom(double i){
    if(i<=0)  System.out.println("Wert fehlerhaft");
    this.strom = i;
    this.leistung = i * this.spannung;    
  }
  
  public double getLeistung(){
    return this.leistung;    
  }
}

Modifier Sichtbarkeit von Variablen und Methoden in Java

Modifier Die Klasse selbst Paket­klassen und innere Klassen Unter­klassen sons­tige Klassen
private
public
protected
ohne

Aufgabe 1 Die Retrobeleuchtung

Erstelle die Klasse Leuchtmittel und Beleuchtung.

  1. Erstelle die Klasse Leuchtmittel und deklariere die Attribute private double spannung, private double strom, private double leistung und private double dimmfaktor.
  2. Erstelle die Methoden:
    public void setSpannung(double u){ },
    public void setStrom(double i){ },
    public double getLeistung(){ },
    public void setDimmfaktor(double f){ },
    public double getDimmfaktor(){ }.
  3. Erstelle die Klasse Beleuchtung. Erzeuge drei Leuchtmittel als Objekte und weiße jedem Leuchtmittel Strom, Spannung zu.
  4. Der Nutzer gibt nun für jedes Leuchtmittel einen Dimmfaktor zwischen 0 und 100 % ein. Gib eine Liste der Helligkeitswerte (in %) und Leistungsbedarf aus.
Retrolampe mit mehreren Leuchtmitteln

Konstruktoren Gib Deinen Objekten Startwerte mit

Mit Hilfe von Konstruktoren kann man beim Erzeugen neuer Objekte, dessen Attribute initialisieren. Der Konstruktor ist eine Methode die beim Erzeugen eines Objekts aufgerufen wird und den identischen Namen wie die Klasse hat. Der Standardkonstruktor für die Klasse Schaf sieht wie folgt aus:

public class Schaf{
  public String name;
  public int alter;

  public Schaf (){  }
}
Zeichnung zweier Schafe

Konstruktoren erstellen

Um nun Standardwerte zu vergeben oder beim Erzeugen des Objekts die Attribute zu setzen, wird die Konstruktormethode überladen.

public class Schaf{
  private String name;
  private int alter;

  public Schaf (){
    this.name="anyname";
  }

  public Schaf (String name, int alter){
    this.name = name;
    this.setAlter(alter);
  }
}
	
public class Schafherde {
  public static void main(String[] args) {
    //Aufruf des Standardkonstruktors
    Schaf s1 = new Schaf();

    //Konstruktoraufruf mit Parameter
    Schaf s2 = new Schaf("Emma",20);
  } 
}

Konstruktoren aufrufen

Konstruktoren werden nun beim Erzeugen der Objekte aufgerufen. Der Aufruf muss entsprechend zu einer der Konstruktormethoden passen.

Aufgabe 2 Ordne zu

Ordne die korrekte Antwort zu.

Nenne die Klasse, welche auf ein private Attribut Zugriff hat.
Wähle eine Antwort.

  1. innere Klassen
  2. die Klasse selbst
  3. Unter­klassen
  4. sons­tige Klassen

Nenne Vorteile der Kapselung.
Wähle zwei Antworten.

  1. fehlerhafte Werte werden verhindert
  2. Objekte werden nicht doppelt erzeugt
  3. Klassen werden geschützt
  4. abhängige Attribute sind geschützt

Finde die Anzahl der Fehler im folgenden Quelltext.

public double setStrom(double i){
  if(i<=0)  System.out.println("Wert fehlerhaft");
  strom = i;
  this.leistung = i * this.spannung;    
}

Finde die Anzahl der Fehler im folgenden Quelltext.

private double leistung;

public int getLeistung(double p){
  return this.leistung;
}

Bestimme die zugehörige Konstruktormmethode, zum Konstruktoraufruf Schaf s2 = new Schaf(20,23.3);. Wähle eine Antwort.

  1. public Schaf(int a, double b){...}
  2. public int Schaf(int a, double b){...}
  3. public Schaf(double alt, int gew){...}
  4. public Schaf(int a, int g){...}

Beschreibe einen Konstruktor.
Wähle beliebig viele Antworten.

  1. ist eine Methode
  2. gibt einen Wert zurück
  3. Name ist identisch mit Klassennamen
  4. kennzeichnet Klassen

Aufgabe 3 set-get-Methoden und Konstruktoren für die Schafe

Die Schafe sollen mit set-get-Fähigkeiten und Konstruktoren ausgestattet werden.

  1. Erweitere die Klasse Schaf mit folgenden set-get-Methoden:
    public void setName(String name) {..}
    public void setAlter(int alter) {..}
    public void setGewicht(double gewicht) {..},
    public void setGewicht(int mengeGras, int mengeKohl ) {..},
    public String getName() {..},
    public int getAlter() {..},
    public double getGewicht() {..}.
  2. Erweitere die Klasse Schaf mit einem neuen Standardkonstuktor:
    public Schaf( ) {..}. Initialisiere den Namen mit "noname", das Alter mit 1 Jahr sowie das Gewicht mit 0.0 kg.
  3. Erweitere die Klasse Schaf mit dem weiteren Konstuktor:
    public Schaf(String name, int alter, double gewicht) {..}.
  4. Teste in der Klasse Schafherde die neuen Methoden und Konstruktoren ausführlich. Lass alle Änderungen der Attribute jeweils anzeigen.
Zeichnung zweier Schafe

Entspann dich erstmal ...



Briefmarken aus dem Jahr 2022

Ein männlicher Briefmark erlebte
Was Schönes, bevor er klebte.
Er war von einer Prinzessin beleckt.
Da war die Liebe in ihm erweckt.

Er wollte sie wieder küssen,
Da hat er verreisen müssen.
So liebte er sie vergebens.
Das ist die Tragik des Lebens!

Aufgabe 4 Der Fuhrpark

Erweitere die Klasse Auto und Fuhrpark.

zwei Autos
  1. Erweitere die Klasse Auto mit set- und get-Methoden.
  2. Setze alle Attribute der Klasse Auto auf private
  3. und stelle so sicher, dass abhängige Attribute nicht falsche Werte haben können und sicher alle Eingaben gegen fehlerhafte Eingaben ab.
  4. Erweitere die Klasse Fuhrpark durch Aufrufe der set- und get-Methoden und teste so die Funktionalität der Klasse Auto.
  5. Erweitere die Klasse Auto mit zwei Konstruktor­methoden, den Standard­konstruktor mit Initalwerten und einem Konstruktor mit Parameterliste.

UML-Klassendiagramme Unified Modeling Language

UML (engl. unified modeling language) ist eine grafische Modellierungssprache zur Spezifikation, Konstruktion und Dokumentation von Software-Teilen und anderen Systemen. UML besteht aus vielen Diagrammtypen. Ein Typ davon ist das Klassendiagramm.

Ein Klassendiagramm stellt eine Klasse übersichtlich und strukturiert dar. Es ist von der Form her rechteckig und besteht aus drei Teilen:

  1. Klassenname,
  2. Attribute (Eigenschaften) mit Modifier (+ für public und - für private) und Datentyp,
  3. Methoden (Fähigkeiten) mit Modifier, Name, Parameterliste und Rückgabetyp.

Man beachte, das statische Methoden und Attribute unterstrichen werden.

Was das Klassendiagramm nicht sagt:

  • es beschreibt nicht was in den Methoden genau passiert und wie diese zu ihrem Ergebnis kommen,
  • es sagt nichts über die Objekte aus, die von der Klasse erstellt werden.
Auto
- farbe : String
- leistung : int
- preis : double
- mehrwertsteuer : double
+ Auto (String farbe, int leistung, double preis)

+ setFarbe (String color) : void
+ setLeistung (int power) : void
+ setMwSt (double mwst) : void

+ getFarbe () : String
+ getLeistung () : int
+ getMwSt () : double

+ fahrenStrecke (int km) : void
+ tanken (int menge) : void

Aufgabe 5 UML-Klassendiagramm

Schreibe UML-Klassendiagramme.

  1. Schreibe ein UML Klassendiagramm für die Klasse Auto.
  2. Schreibe ein UML Klassendiagramm für die Klasse Fuhrpark.
  3. Schreibe ein UML Klassendiagramm für die Klasse Schaf.
Zeichnung zweier Autos

Aufgabe 6 Weitere Projekte

Schreibe weitere Klassenpaare.

Pizzastücke

Neben den Klassenpaaren Schaf und Schafherde sowie Auto und Fuhrpark, gibt es weitere Klassenpaare.

  1. Schreibe ein UML Klassendiagramm für die Klassen Wohnmobil und Campingplatz.
  2. Schreibe ein UML Klassendiagramm für die Klassen Pizza und Menue.
  3. Schreibe ein UML Klassendiagramm für die Klassen Sensor und Home.
  4. Nenne drei weitere Klassenpaare aus der Praxis und programmiere eins davon.

Automatisierte Objektauswertung Objekte in einer ArrayList speichern

Speichert man die verschiedenen Objekte direkt beim Erzeugen in einer ArrayList können mit Hilfe von Schleifen automatisierte Ausgaben und Auswertungen aller Objekte generiert werden. Dabei muss im Vergleich zu einem array die genaue Anzahl der Objekte vorab nicht bekannt sein. Mit der add(..) Methode wird ein Element dem Container hinzugefügt.

import java.util.ArrayList;
public class SchafherdeArrayList {
  public static void main(String[] args) {
    //Anlegen einer ArrayList namens schafListe
    ArrayList<Schaf> schafListe = new ArrayList<Schaf>();
    //Hinzufügen von Einträgen mit der Methode add(..)
    schafListe.add(new Schaf("Emma", 20, 50.0));
    schafListe.add(new Schaf("Berta", 8, 30.0));
  }
}
	
Zeichnung zweier Schafe

Konstruktoren erstellen

Um nun Standardwerte zu vergeben oder beim Erzeugen des Objekts die Attribute zu setzen, werden entsprechende Konstruktormethoden erstellt.

Des weiteren benötigen wir wie gehabt entsprechende set- und get-Methoden.

public class Schaf{
  private String name;
  private int alter;
  private double gewicht;

  //Konstruktor
  public Schaf (String n, int a, double g){
    this.name = n;
    this.alter = a;
    this.gewicht = g;
  }

  //set- und get-Methoden
  ...
}
//Ausgabe aller Schafe und deren Alter
for (int i=0; i<schafListe.size(); i++) {
  Schaf schaf = schafListe.get(i);
  System.out.println("Schaf "+(i+1)+": "+schaf.getName());
  System.out.println("Alter: "+schaf.getAlter());
}
		
//Berechnung des mittleren Herdenalters
int gesamt = 0;		
for (Schaf schaf: schafListe) {
  gesamt += schaf.getAlter();
}
double herdenalter = (double)gesamt/schafListe.size();
System.out.printf("Herdenalter: %.1f",herdenalter);

Automatisierte Ausgabe und Auswertung

In der for-Schleife wird über die size() Mehtode die Anzahl der Elemente abgefragt. Die get(..) Methode gibt das Element am angegebenen Index zurück.

for-each-Schleifen iterrieren über alle Daten­strukturen deren Elemente aufzählbar sind. In Java werden diese mit dem : Operator gekenn­zeichnet. Dabei ist Schaf der Datentyp des Elements und schaf das Elementobjekt welches aktuell betrachtet wird. Das Containerobjekt schafListe gehört zur Klasse ArrayList.

Aufgabe 7 Bücherei

Realisiere eine Bücherei in der Bücher mit Titel, Autor und Bewertung gespeichert werden sollen.

Bücherstapel
  1. Erstelle das Klassenpaar Book und Library.
  2. Füge zur Klasse Book die Attribute title, author, rating hinzu sowie entsprechende set- und get-Methoden.
  3. Füge zur Klasse Library eine ArrayList namens booklist hinzu und erzeuge drei Einträge wie bspw. booklist.add(new Book("Herr der Ringe", "J.R.R. Tolkien", 4.8));.
  4. Gib alle Einträge aus.
  5. Berechne die durchschnittliche Bewertung aller Bücher.

Aufgabe 8 Ordne zu

Ordne die korrekte Antwort zu.

Für Objekte der Klasse Schaf soll eine ArrayList erstellt werden.
Wähle eine Antwort.

  1. ArrayList box = new ArrayList();
  2. ArrayList<Schaf> box = ArrayList<Schaf>();
  3. ArrayList<Schaf> box = new ArrayList<Schaf>();
  4. ArrayList schafListe = new ArrayList();

Erkläre die Klasse ArrayList.
Wähle eine Antwort.

  1. die Klasse dient als Container für Arrays
  2. die Klasse erstellt eine Liste mit Arrays
  3. die Klasse erzeugt eine ungeordnete Liste
  4. die Klasse dient als Container für Objekte

Finde die Anzahl der Fehler im folgenden Quelltext.

import java.util.ArrayList;
public class Pizzamenu {
  public static void main(String[] args) {
    ArrayList menue = new ArrayList();
    menue1.add(new schaf());
  }
}

Finde die Anzahl der Fehler im folgenden Quelltext.

public class Pizza{
  private String name;
  public Pizza (String name, double preis){
    this.name = namen;
    this.preis = preis;
  }
}

In der ArrayList box sind 3 Schafe im Alter von jeweils 3 Jahren.
int i = 3;
for (Schaf schaf: box) {
  i += schaf.getAlter()-1;
}

Bestimme den Wert von i. Wähle eine Antwort.

  1. i hat den Wert 3
  2. i hat den Wert 12
  3. i hat den Wert 9
  4. der Quelltext ist fehlerhaft

In der ArrayList box sind zwei Schafe namens Emma und Berta.
for (int i=0; i<box.size(); i++) {
  Schaf schaf = box.get(i);
  System.out.print(schaf.getName());
}

Bestimme die Ausgabe. Wähle eine Antwort.

  1. EmmaBerta
  2. Emma, Berta
  3. Emma\nBerta
  4. weder noch

Wortliste und Satzbausteine



das Objekt, -e Objekte haben Eigenschaften (engl. states) und Fähigkeiten (engl. behaviors). Diese werden in einer zugehörigen Klasse festgelegt.
die Klasse, -n Eine Klasse beschreibt, welche Eigenschaften und Fähigkeiten ein Objekt haben darf und stellt somit den Bauplan von Objekten bereit.
die Methode, -en Fähigkeiten von Objekten werden in Methoden beschrieben.
das Attribut, -en Eigenschaften von Objekten werden in Attributen (Variablen) festgelegt.
der Modifier, ~ legt die Sichtbarkeit von Eigenschaften und Fähigkeiten fest, also ob diese bspw. privat oder öffentlich zugänglich sind
die Kapse­lung, - die Sichtbarkeit der Attribute einer Klasse wird auf private gesetzt und so schirmt man die Attribute vom Zugriff aus anderen Klassen ab.
die set-, get-Me­thoden, - Methoden die die abgeschirmten Attribute setzen oder auslesen.
der Konstruk­tor, -en Methode welche die Initialisierung der Parameter bei Objekterzeugung ermöglicht
das Überla­den des Konstruk­tors Existieren mehrere Methoden gleichen Namens spricht man vom Überladen. So kann bspw. mit mehreren Konstruktoren ein unterschiedlicher Initialisierungsgrad erreicht werden.
die ArrayList eine Klasse, die als Container für eine Liste von Objekten dient