Was sind Schnittstellen (Interfaces)?

Interfaces ermöglichen eine spezielle Form der Mehrfachvererbung, da es in Java nicht erlaubt ist, eine Klasse von mehreren Superklassen abzuleiten.

Interfaces dienen oft dazu sicherzustellen, dass bestimmte Fähigkeiten oder Eigenschaften in den das Interface implementierenden Klassen enthalten sind. Eine Schnittstelle wird mit dem Schlüsselwort interface statt des Klassen kennzeichnenden class bezeichnet und ihr Bezeichner wie der von Klassen mit großem Anfangsbuchstaben geschrieben. Sie enthält keinerlei Implementierungen und ist aus diesem Grund immer abstract, ohne dass dies gesondert angegeben werden muss.
Entsprechend sind alle Methodendeklarationen ebenfalls abstract und dürfen als Zugriffsmodifizierer nur abstract und public enthalten. Da diese Eigenschaften bei Interface-Methoden jedoch immer implizit vorhanden sind, werden diese Modifikatoren selten verwendet. Alle Methoden müssen in den das Interface implementierenden Klassen implementiert werden, es sei denn, die implementierende Klasse ist selbst abstract deklariert.

Interfaces können Konstanten enthalten. Sie werden durch Feld-Deklarationen definiert und entsprechen public, static und final deklarierten Variablen. Durch Verwenden des voll qualifizierten Namens (<Interfacebezeichner>.<Konstantenbezeichner>) können sie, ähnlich Klassenvariablen, durch alle Klassen und Interfaces angesprochen werden, unabhängig davon, ob der Client eine das Interface implementierende Klasse oder ein das Interface erweiternde Schnittstelle ist. Ist dies jedoch der Fall, so kann die Konstante auch direkt durch ihren Bezeichner angesprochen werden.

Implementiert eine Klasse eine oder mehrere Schnittstellen, so wird ihr Bezeichner vom Schlüsselwort implements und der Komma-separierten Liste der Interfaces gefolgt.

public class InterfaceBsp {
    public static void main(String[] args) {
        Fahrrad f = new Fahrrad();
        System.out.println("Tempo des Fahrrads: " + f.tempo);
        f.beschleunigen(10);
        System.out.println("Tempo des Fahrrads: " + f.tempo);
        f.verzoegern(8);
        System.out.println("Tempo des Fahrrads: " + f.tempo);
        
        MotoGuzzi m = new MotoGuzzi();
        System.out.println("Tempo des Motorrads: " + m.tempo);
        m.beschleunigen(50);
        System.out.println("Tempo des Motorrads: " + m.tempo);
        m.verzoegern(36);
        System.out.println("Tempo des Motorrads: " + m.tempo);
    }
}

interface Drivable {

    int RAEDER = 2; // implizit public static final

    void beschleunigen(double d);

    void verzoegern(double d);
}

class Fahrrad implements Drivable {
    
    double tempo=0;

    @Override
    public void beschleunigen(double faktor) {
        if(faktor < 0) return;
        tempo += faktor * 1.5;
        tempo = tempo > 50 ? 50 : tempo;
    }

    @Override
    public void verzoegern(double faktor) {
        if(faktor < 0) return;
        tempo -= faktor * 1.2;
        tempo = tempo < 0 ? 0 : tempo;
    }
}

class MotoGuzzi implements Drivable {
    
    double tempo=0;

    @Override
    public void beschleunigen(double faktor) {
        if(faktor < 0) return;
        tempo += faktor * 6.3;
        tempo = tempo > 200 ? 200 : tempo;
    }

    @Override
    public void verzoegern(double faktor) {
        if(faktor < 0) return;
        tempo -= faktor * 4.6;
        tempo = tempo < 0 ? 0 : tempo;
    }
}

Das Beispiel demonstriert die typische Art der Verwendung eines Interface. Die grundlegenden Fähigkeiten eines Fahrzeug werden im Interface Drivable durch die Methoden beschleunigen() und verzoegern() definiert. Eine Konstante legt die Anzahl der Räder fest. Sie kann in den beiden implementierenden Klassen nicht überschrieben werden. Die Methoden hingegen werden in beiden Klassen Fahrrad und MotoGuzzi jeweils individuell implementiert und bestimmen den Wert der Instanzvariablen tempo.

Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.