web-dev-qa-db-fra.com

Si j'appelle une méthode d'interface, le corps de la méthode sera-t-il extrait de la classe d'implémentation et exécuté?

J'ai une interface Interface1. J'ai son implémentation Imple implements Interface1 (toutes les méthodes ont été implémentées :)).

Maintenant, considérons une troisième classe CheckCall, puis-je faire un appel dans la classe CheckCall comme je le mentionne ci-dessous:

Interface1 interface1;
interface1.method();

Toutes les importations nécessaires ont été effectuées. Dites-moi s'il vous plaît si c'est possible ou non, sinon ok et si oui, alors dites-moi ce qui se passera si j'ai plus d'une classe implémentée pour la même interface et que je fais le même appel.

15
sij

Eh bien, vous ne pouvez pas appeler la méthode directement sur l'interface, mais vous pouvez faire ce que vous avez écrit, plus ou moins.

Tu as écrit:

Interface1 interface1;
interface1.method();

Cela fonctionnera si vous faites ceci:

Interface1 interface1 = new CheckCall();
interface1.method();

puis dites-moi ce qui se passera si ai plusieurs classes impl pour la même interface et que je fais le même appel.

Eh bien, c’est la bonne chose à propos de Java: le problème dont vous parlez s’appelle le "problème du diamant":

http://en.wikipedia.org/wiki/Diamond_problem

Et cela n’existe pas vraiment en Java, car Java supporte pleinement l’héritage multiple, mais uniquement via "héritage d’interface multiple (Java)" (* voir le commentaire).

Ainsi, dans votre cas, lorsque vous appelez interface1.method(), vous appelez soit la méthode Impl, soit la méthode CheckCall, et aucune confusion n'est possible.

14
SyntaxT3rr0r

Bien sûr, votre code fonctionne bien! Vous devez simplement initialiser votre variable interface1 avec une implémentation réelle (c'est-à-dire new Imple ()).

Regardez cet exemple, j'ai utilisé vos noms de classe:

public class CheckCall {

    interface Interface1 {
        void method();
    }

    static class Imple implements Interface1 {
        @Override
        public void method() {
            System.out.println("Imple.method1()");
        }
    }

    public static void main(String[] args) {
        Interface1 interface1;
        interface1 = new Imple();
        interface1.method();
    }

}
7
slartidan

Oui, mais pas comme vous l'avez écrit. Il faudrait dire:

Interface1 interface1 = new Imple();

Vous pouvez créer une variable de type Interface, puis l'instancier à la classe qui implémente l'interface. Vous le voyez assez souvent avec les collections Java, par exemple:

List<String> a = new ArrayList<String>();
5
Riggy

En fait, vous devriez faire référence aux méthodes par les interfaces qui les définissent, mais vous avez besoin d’une classe d’implémentation réelle. Donc, je le ferais habituellement comme ça:

// the variable is of type Interface1
Interface1 interface1 = new Imple();
// but the method will be executed on the Imple object
interface1.method();
1
Sean Patrick Floyd

Non, vous devez effectuer l'appel sur l'objet qui implémente l'interface, pas sur l'interface elle-même. 

Edit: une variable de ce type pourrait être utilisée mais il faudrait quand même que ce soit une classe qui implémente ce type. Vous ne pouvez pas créer une instance d'une interface.

0
jzd

Non.

Comme vous ne pouvez pas instancier une interface, vous devez créer un objet Imple, pour l'utiliser en tant que Interface1 comme ceci:

Interface1 interface1 = new Imple();

interface1.method();

en fait, un des principaux intérêts de l'interface provient de la possibilité pour une méthode de retourner n'importe quel objet l'implémentant, sans avoir à s'inquiéter d'une implémentation donnée. dans votre cas, il pourrait apparaître comme

public class CheckCall {
    public Interface1 factoryMethod() {
        return new Imple();
    }

    public void test() {
        Interface1 used = factoryMethod();

        used.method();
    }
}
0
Riduidel