8.4 Abstrakte und finale Klassen

Finale Klassen und Methoden

Java bietet die Möglichkeit Klassen und Methoden zu implementieren die nicht mehr abgeleitet oder überschrieben werden dürfen. Hierzu dient das Schlüsselwort final.

Finale Methoden

Mit dem Schlüsselwort final kann man das Überschreiben der Methode in einer Unterklasse unterbinden. Ein typsiches Beispiel hierfür ist:

public final void print() { /* Methodenrumpf */}

Unterklassen mit überschriebenen Methoden sind ein sehr mächtiges Konzept für den Entwickler einer Unterklasse. Eine Unterklasse kann inhaltlich eine Oberklasse in weiten Bereichen neu implementieren, solange die Signaturen der Methoden gewahrt bleiben und ein Konstruktor der Oberklasse benutzt. Die Kontrolle liegt fast vollständig in den Händen der Unterklasse. das Schlüsselwort final erlaubt dem Entwickler der Oberklasse

  • das Überschreiben zu verbieten
  • und damit die Sichtbarkeit der Methode der Oberklasse für beliebige Konsumenten der Unterklasse zu garantieren

Dem Entwickler der Unterklasse steht es nach wie vor frei Methoden mit anderen Signaturen zu verwenden.

Finale Klassen

Finale Klassen verbieten die Spezialisierung einer Klasse durch eine Unterklasse.

Das Schlüsselwort final kommt im folgenden Beispiel zum Einsatz:

final class chiefExecutiveOfficer extends Manager { /* Klassen Implementierung */} 

Beispiel

  • Systemklasse String: Die Klasse String ist final, da Zeichenketten hochoptimiert und nicht veränderbar sind. Das Javalaufzeitsystem verwendet spezielle Optimierungen wie Stringpools und es nutzt die Unveränderbarkeit von Zeichenketten um dem Anwender Zugriff auf spezielle Zeichenketten des Laufzeitsystems zu geben. Die Möglichkeit diese Klasse zu spezialisieren wurde unterbunden um Sicherheit und Leistung zu garantieren.

Abstrakte Klassen und Methoden

Abstrakte Klassen

Abstrakte Klassen und Java-Schnittstellen (Stoff des zweiten Semester) dienen in Java zur Modularisierung und damit oft zur Arbeitsteilung zwischen Entwicklern. Abstrakte Klassen erlauben es dem Entwickler eine Oberklasse zu implementieren die nicht selbst instanziiert werden darf. Dieses Konzept erlaubt es Klassen als Vorlagen zu implementieren und gleichzeitig zu erzwingen, dass die Entwickler der Unterklasse fehlende oder eigene Methoden und Attribute zur Verfügung stellen. Hiermit lassen sich allgemeine Konzepte implementieren die zu allgemein sind um Instanziierungen zu erlauben, Dies erfolgt mit dem Schlüsselwort abstract bei der Spezifikation der Klasse.

Die Klasse Person im vorhergehenden Beispiel ist eine Klasse von der man nicht erlauben möchte, dass sie instanziiert wird. Dies geschieht zum Beispiel so:

public abstract class Person {
    private String name;
    private String firstName;
    public int age;

    public Person(String ln, String fn) {
        name = ln; firstName = fn; }

    public Person() { this("Doe","John");}

    public void setName(String ln, String fn) {
        name = ln; firstName = fn; }
    public String fullName() {return (name + " " + firstName);}
}

Versucht man nun eine Person zu instanziieren:

Person p1 = new Person("persona","nongrata");

...führt dies beim Übersetzen zu folgendem Fehler:

javac Main.java 
Main.java:8: Person is abstract; cannot be instantiated
        Person p1 = new Person("persona","nongrata");
                    ^
1 error

Abstrakte Klassen haben die typischen Eigenschaften von normalen Javaklassen. Sie haben Attribute und Methoden die vererbt werden können.

Wichtige Eigenschaften abstrakter Klassen
  • Sie können nicht instanziiert werden.
  • Sie können nicht final sein.

Beispiel

Die Systemklasse Number: Die Klasse Number enthält gemeinsame Methoden für zahlenartige Typen. Man kann sie jedoch nicht direkt instanziieren. Die daraus abgeleiteten Klassen Byte, Float etc. sind final. Sie sind hochoptimiert und sollen aus Performance- und Sicherheitsgründen nicht spezialisiert werden.

Abstrake und finale Klassen

Abstrakte Methoden

Normale Methoden und Attribute werden an die Unterklasse vererbt und können auch bei Bedarf überschrieben werden.

Wird jedoch eine Methode mit dem Schlüsselwort abstract gekennzeichnet so muss sie von einer nicht abstrakten Unterklasse implementiert und überschrieben werden.

Beispiel

Die Klasse Person kann so erzwingen, dass eine printAll() Methode für alle Unterklassen implementiert muss, ohne sie selbst zu implementieren.

public abstract class Person {
    private String name;
    private String firstName;
    public int age;

    public Person(String ln, String fn) {
        name = ln; firstName = fn; }

    public Person() { this("Doe","John");}

    public void setName(String ln, String fn) {
        name = ln; firstName = fn; }
    public String fullName() {return (name + " " + firstName);}
    public abstract String printAll();
}

Regel: Eine Unterklasse einer abstrakten Klasse muss:

  • alle abstrakten Methoden implementieren um nicht "abstrakt" zu sein

oder

  • selbst eine abstrakte Klasse sein, falls sie nicht alle oder keine der abstrakten Methoden implementiert.

 

T.B. (not verified)

Thu, 12/03/2020 - 18:08

Bei dem ersten Satz nach der Überschrift „Finale Methoden“ fehlt das Verb „kann“.