web-dev-qa-db-fra.com

Le tutoriel Java dit que je peux avoir une interface paquet-privé, mais je ne peux pas

Dans le Tutoriel Java "Définition d’une interface" , il est indiqué 

Si vous ne spécifiez pas que l'interface est public, votre interface ne sera accessible qu'aux classes définies dans le même package que l'interface.

Cependant, cela 

interface PPInterface {
    void foo();
    void bar();
}

class NewClass implements PPInterface {
    void foo() {}
    void bar() {}
}

génère des erreurs de compilation dans NewClass parce que je «tente d’attribuer des privilèges d’accès plus faibles; était public '. Donc, la documentation est fausse, ou j'ai fait quelque chose de mal, ou j'ai mal interprété la documentation?

Je suppose que je n'ai pas besoin d'utiliser une interface - j'aime bien parce que ça garde les choses bien organisées.

29
Pete

C'est l'interface elle-même qui peut être privée de paquet, pas les méthodes qu'elle contient. Vous pouvez définir une interface qui ne peut être utilisée (par nom) que dans le package dans lequel elle est définie, mais ses méthodes sont public comme toutes les méthodes d'interface. Si une classe implémente cette interface, les méthodes qu'elle définit doivent être public. La chose clé ici est que c'est l'interface type qui n'est pas visible en dehors du paquet, pas les méthodes. Les documents ne sont pas incorrects car utiliser les méthodes définies dans l'interface n'est pas la même chose que utiliser l'interface elle-même.

Sachez également que lors de la définition d'une interface, ne pas ajouter public avant une définition de méthode ne change rien, car les méthodes sont toutes implicitement public.

Si les classes que vous avez implémentées pour l'interface sont elles-mêmes privées du paquet, la valeur publicness des méthodes d'interface n'est évidemment pas un problème. Vous pouvez aussi, bien sûr, utiliser une classe abstraite au lieu d'une interface si le problème de l'héritage unique ne vous gêne pas:

abstract class Whatever {
  abstract void foo();
  abstract void bar();
}
54
ColinD

Je pense (même si je peux me tromper à ce sujet), les privilèges d'accès les plus faibles dont il est question ici concernent les méthodes foo() et bar() dans NewClass. Toutes les méthodes d'interface sont implicitement public, mais dans NewClass vous leur avez laissé package-private, ce qui est une garantie plus faible que public. Changer NewClass pour lire 

class NewClass implements PPInterface{
    public void foo() {}
    public void bar() {}
}

probablement va résoudre ce problème.

4
templatetypedef

ce qui a fonctionné pour moi pour contourner le problème de l'héritage unique:

Au lieu de A s'étend B implémente C

J'ai abstrait D (paquet protégé interface en C) étend B

et puis A étend D

Fonctionne bien. Propre aussi, tbh.

0
Blaze