###### tags: `Klasse10` `Informatik`
# Eigene Klassen, Konstruktoren und Vererbung
## Eine Buntstiftklasse
---
### Aufgabe 1:
a) Schreibe eine Klasse `Buntstift` , mit dem Attribut `farbe` und einem Konstruktor, der beim Erzeugen eines Objektes den Attributwert für die Farbe erwartet und diesen dem Attribut `farbe` zuweist.
Weiterhin hat die Klasse eine Methode `schreibe`, die als Eingabewert einen Text (Datentyp String) erwartet und diesen in der Farbe des Buntstifts auf den Bildschirm schreibt.
b) Erzeuge ein Objekt `rotstift` und ein Objekt Objekt `blaustift`, das einen roten bzw. blauen Stift erzeugt und schreibe den Text "Ich bin rot" bzw. "Ich bin blau" auf den Bildschirm.
---
### Aufgabe 2:
Es wird nun eine weitere Stiftklasse benötigt, die zusätzlich zur Farbe auch noch die Möglichkeit besitzen soll, den gesamten Text in Großbuchstaben zu schreiben.
Wir verwenden hierfür die Klasse `Buntstift` als Oberklasse und definieren hierzu eine Unterklasse `StiftNeu`, die zusätzlich zum Attribut `farbe` auch noch ein Attribut **`grossschreibung`** besitzen soll, dass speichert, ob ein Objekt dieser Klasse alle Buchstaben in Großbuchstaben schreibt oder nicht.
---
a) Schreibe die Unterklasse `StiftNeu`, die von `Buntstift` erbt und das zusätzliche Attribut `grossschreibung` besitzt.
---
b) Die Methode `schreibe()`soll nun angepasst werden. D.h. je nach Wert des Attributs `grossschreibung` soll der eingegebene Text groß geschrieben werden oder nicht.
---
Für das Großschreiben eines Textes kann dieser mit Hilfe der Stringfunktion `toUpperCase()` in Großbuchstaben umgewandelt werden. D.h. mit
```java
text = text.toUpperCase();
```
Die Methode `schreibe()` wird in der Unterklasse **überschrieben**, d.h. sie wird spezialisiert. Zur Kennzeichnung, dass es in der Oberklasse eine gleichlautende Methode gibt, wird vor die Methode in der Unterklasse häufig die Kennung **`@override`** hinzugefügt.
```java=
@override
public void schreibe(String text){
if(grossschreibung){
text = text.toUpperCase();
}
println(text);
}
```
---
### Das Schlüsselwort "super"
Möchte man in der Unterklasse auf Methoden aus der Oberklasse verweisen, so wird das Schlüsselwort **`super`** verwendet. Somit kann die Methode von oben auch folgendermaßen geschrieben werden:
```java=
@override
public void schreibe(String text){
if(grossschreibung){
text = text.toUpperCase();
}
super.schreibe();
}
```
D.h. die Methode `schreibe()` aus der Unterklasse ruft mit `super.schreibe()` die Methode aus der Oberklasse auf.
---
### Konstruktor in der Unterklasse
Eine Unterklasse verwendet, wenn nichts anderes angegeben wird, den Konstruktor aus der Oberklasse. Um nun einen speziellen Konstruktor für die Unterklasse zu verwenden, muss zunächst der Konstruktor aus der Oberklasse mit **`super(...)`** mit den entsprechenden Eingabeparametern aufgerufen werden und anschließend ergänzt werden.
Der Konstruktor aus der Klasse `StiftNeu` könnte demnach folgendermaßen aussehen:
```java=
public StiftNeu(String farbeNeu, boolean grossschreibungNeu){
super(farbeNeu); //ruft den Konstruktor der Klasse Buntstift auf
grossschreibung = grosschreibungNeu;
}
```
---
### Aufgabe 3:
Ergänze die Unterklasse `StiftNeu` mit dem Konstruktor einschließlich der Festlegung für das Attribut ``grossschreibung``
---
### Zugriffsmodifikator "protected"
Die überschriebene Methode `schreibe(...)` verwendet die Methode `schreibe(...)` aus der Oberklasse Buntstift. Eine andere Lösungsmöglichkeit wäre, die Ausführung des `println(text,farbe)`-Befehls. Hierbei stoßen wir jedoch auf ein Problem: wird das vererbte Attribut `farbe` in der Unterklasse aufgerufen, so scheint plötzlich die Klasse dieses nicht mehr zu kennen.
Die ist eine Folge des zugewiesenen Zugriffsmodifikator "private" in der Oberklasse. Dieser lässt keinen Zugriff zu für Objekte, die nicht aus dieser Klasse erzeugt wurden, auch nicht für Objekte aus Unterklassen. Um diesen Zugriff zu erlauben, muss der Zugriffsmodifikator für die Attribute der Oberklasse von "**private**" auf "**protected**" geändert werden. Dies bewirkt, dass der Zugriff nur für Objekte der eigenen Klasse oder Objekte von Unterklassen erlaubt wird.
Mit der Attributdeklaration
```java
protected String farbe;
```
in der Klasse `Buntstift` kann nun in der Klasse `Stiftneu` auch in der Methode `schreibe(...)` der Aufruf
``` java
println(text,farbe);
```
erfolgen und das geerbte Attribut `farbe` verwendet werden.
---
### Aufgabe 4:
Verändere die Methode `schreibe(...)` in der Klasse `StiftNeu` so, dass die `println(...`)-Anweisung mit dem Attribut `farbe` aufgerufen werden kann.
---