it-swarm.com.de

Vererben Unterklassen Schnittstellen?

Kurze Frage, ich lerne etwas über Schnittstellen und Vererbung.

Dies ist kein tatsächlicher Code, nur ein Beispiel. Nehmen wir an, ich habe die abstrakte Klasse Animal. Es gibt eine Vererbung mit Gruppen wie Pferden und Hunden. Es gibt auch eine Schnittstelle "Haustiere". Es wird für verschiedene Unterklassen von Animal verwendet. Die Unterklasse des Hundes "Dog" implementiert die Schnittstelle "Pets". Aus diesem Grund implementieren alle Unterklassen von "Dog" auch die Schnittstelle "Pet", ohne "Pets" für jede Unterklasse von "Dog" einzeln implementieren zu müssen, oder?

33
munchschair

Wenn Sie haben:

abstract class StaffMember implements MyInterface

wo

interface MyInterface {
    void myMethod();
} 

dann erben alle Klassen, die StaffMember erweitern, den Typ MyInterface, und Sie können in anderen Teilen des Codes, in denen eine MyInterface-Instanz als Operand/Argument erwartet wird, mit diesem Basistyp auf sie verweisen. Beispiel:

void otherMethod(MyInterface param) { //... }

Die eigentliche Implementierung des Interfaces MyInterface kann entweder in der abstrakten Klasse oder in einer der Klassen erfolgen, die die abstrakte Klasse erweitern. In diesem Fall ist es einfach wichtig, dass myMethod () irgendwo in der Vererbungshierarchie angegeben wird, damit die JVM eine Definition für den Aufruf finden kann.

17
csvan

Nein.

Eine Schnittstelle definiert, wie eine Klasse aussehen soll (zumindest). Ob Sie dies in einer Basisklasse oder in der untersten Unterklasse implementieren, spielt keine Rolle.

Die Schnittstelle muss vollständig in der Hierarchie der Unterklassen und Basisklassen implementiert und auf der Ebene definiert werden, auf der sich die Signatur der Schnittstellenimplementierung befindet (implements Interface).

Die Unterklassen selbst haben keine Kenntnis über die Schnittstelle, aber sie haben die implizite Verbindung über ihre Basisklasse.

Weil ich eine freundliche Person bin:

public class Test {
    public static void main(String[] args) {
        BaseClass obj = new SubClass();
        obj.test();
        obj.test2();

        SomeInterface obj2 = new SubClass();
        obj2.test();
        obj2.test2();
    }
}

interface SomeInterface {
    public void test();

    public void test2();
}

abstract class BaseClass implements SomeInterface {
    @Override
    public abstract void test();

    @Override
    public void test2() {
        try {
            System.out.println(Arrays.toString(this.getClass().getMethod("test2", null).getDeclaringClass().getInterfaces()));
        } catch (NoSuchMethodException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }   
}

class SubClass extends BaseClass {
    @Override
    public void test() {
        try {
            System.out.println(Arrays.toString(this.getClass().getMethod("test", null).getDeclaringClass().getInterfaces()));
        } catch (NoSuchMethodException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

}   

}

Ausgabe:

[]
[interface SomeInterface]
[]
[interface SomeInterface]

Wie Sie sehen, gibt test() (das in SubClass implementiert ist) keine implementierten Schnittstellen zurück, während test2() (das in BaseClass implementiert ist) ] _) zeigt, dass eine Schnittstelle von dieser Klasse implementiert wird. Abstrakte Klassen können die Implementierung der Methoden von einer von ihnen implementierten Schnittstelle in Unterklassen ermöglichen, indem die Definition als abstract markiert wird.

Und wie Sie in der main -Methode sehen können, funktioniert das Definieren des Objekts als BaseClass oder SomeInterface und macht keinen Unterschied.

11
Jeroen Vannevel