web-dev-qa-db-fra.com

Les sous-classes héritent-elles des interfaces?

Question rapide, j'apprends les interfaces et l'héritage.

Ce n'est pas du code réel, juste un exemple. Disons que j'ai la classe abstraite Animal. Il y a un héritage avec des groupes comme les chevaux et les chiens. Il y a aussi une interface "Pets". Ça va être utilisé sur différentes sous-classes d'animaux. La sous-classe canine "Dog" implémente l'interface "Pets". Par conséquent, toutes les sous-classes de "Dog" implémentent également l'interface "Pet" sans avoir à implémenter individuellement "Pets" sur chaque sous-classe de "Dog", non?

33
munchschair

Si tu as:

abstract class StaffMember implements MyInterface

interface MyInterface {
    void myMethod();
} 

alors toutes les classes étendant StaffMember hériteront du type MyInterface, et vous pourrez y faire référence par ce type de base dans d'autres parties du code où une instance MyInterface est attendue comme opérande/argument, par exemple:

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

L'implémentation réelle de l'interface MyInterface peut avoir lieu soit dans la classe abstraite, soit dans n'importe quelle classe étendant la classe abstraite. L'important est simplement, dans ce cas, que myMethod () soit spécifié quelque part dans la hiérarchie d'héritage, afin que la JVM puisse en trouver une définition à invoquer.

17
csvan

Non.

Une interface définit à quoi devrait ressembler une classe (au minimum). Que vous implémentiez cela dans une classe de base ou dans la sous-classe la plus basse n'a pas d'importance.

L'interface doit être entièrement implémentée dans toute la hiérarchie des sous-classes et de la classe de base et doit être définie au niveau où se trouve la signature d'implémentation de l'interface (implements Interface).

Les sous-classes elles-mêmes n'ont aucune connaissance de l'interface, mais elles ont la connexion implicite via leur classe de base.

Parce que je suis une personne gentille:

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();
        }

}   

}

Sortie:

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

Comme vous pouvez le voir, cela montre que test() (qui est implémentée dans SubClass) ne renvoie aucune interface implémentée, tandis que test2() (qui est implémentée dans BaseClass) montre qu'une interface est implémentée par cette classe. Les classes abstraites peuvent permettre d'implémenter les méthodes à partir d'une interface qu'elles implémentent pour être implémentées dans des sous-classes en marquant la définition comme abstract.

Et comme vous pouvez le voir dans la méthode main, la définition de l'objet comme BaseClass ou SomeInterface fonctionne et ne fait aucune différence.

11
Jeroen Vannevel