web-dev-qa-db-fra.com

Protégé dans les interfaces

Pourquoi toutes les méthodes d'une définition interface implicitement public? Pourquoi n'autorise-t-il pas une méthode protected?

93
Swaranga Sarma

Parce qu'une interface est censée signifier "ce que vous pouvez voir de l'extérieur de la classe". Il ne serait pas logique d'ajouter des méthodes non publiques.

59
Raveline

Bien que la raison souvent citée soit que "les interfaces définissent les API publiques", je pense que c'est une simplification excessive. (Et ça "sent" la logique circulaire aussi.)

  • Une interface imbriquée peut être protégée ou privée et, dans ce cas, elle ne définit pas du tout une interface publique.

  • Il ne serait pas inutile de disposer d'interfaces combinant plusieurs modificateurs d'accès. par exemple. partiellement public et partiellement limité à d'autres classes du même package que l'interface. En fait, dans certains cas, cela pourrait être utile, IMO. 

En fait, je pense que la partie du raisonnement pour rendre implicitement les membres d'une interface publique est que (cela simplifie Java):

  • Les membres d'interface publics implicitement sont plus simples à gérer pour les programmeurs. Combien de fois avez-vous vu du code (classes) où les modificateurs d'accès aux méthodes ont été choisis apparemment au hasard? Beaucoup de programmeurs "ordinaires" ont du mal à comprendre comment gérer au mieux les limites d'abstraction Java.1. L'ajout de public/protected/package aux interfaces rend la tâche encore plus difficile. 

  • Les membres d'interface publics implicitement simplifient la spécification du langage ... et donc la tâche des rédacteurs de compilateur Java et des personnes qui implémentent les API de Reflection.

Cette ligne de pensée fait des "interfaces de définition des API publiques" une conséquence (ou caractéristique) de la conception du langage ... et non l'inverse. En réalité, les deux courants de pensée se sont probablement développés parallèlement dans l'esprit des concepteurs de Java.


1 - Bien sûr, les programmeurs de premier plan n’ont aucune difficulté avec ces choses et peuvent souhaiter une palette plus riche de fonctionnalités de contrôle d’accès. Mais que se passe-t-il lorsque leur code est confié à une autre personne à entretenir?

47
Stephen C

Je dois dire que cette question a été rouverte par l’introduction des méthodes par défaut dans Java 8. Le projet sur lequel je travaille actuellement est semblable à la nature de base d’une interface conçue pour extraire l’intention de l’implémentation.

Il existe plusieurs cas dans lesquels je pourrais simplifier considérablement mon code avec une méthode "protégée par défaut". Il s'avère que cela ne fonctionne pas réellement, car les interfaces restent liées à la logique Java 7. Une méthode protégée normale n’a aucun sens, pour les raisons mentionnées ci-dessus; mais si une méthode publique par défaut nécessite une ressource de bas niveau qui ne changera probablement pas et qui peut être fournie par une méthode protégée, il me semble qu'avoir un travail "protégé par défaut" permettrait non seulement de conserver un code plus propre, il protégerait les futurs utilisateurs abus accidentels.

(Cela ne change tragiquement pas le fait que je dois encore trop compliquer mon code avec des résumés par ailleurs inutiles; mais j'ai l'intention de faire une demande de fonctionnalité à Oracle.)

17
Michael Oberlin

Parce que les interfaces définissent des API publiques. Tout ce qui est protégé est un détail interne qui n'appartient pas à une interface.

Vous pouvez utiliser des classes abstraites avec des méthodes abstraites protégées, mais les interfaces sont limitées aux méthodes publiques et aux champs finaux statiques publics.

9
Sean Patrick Floyd

Peut-être, car il s’agit d’une interface , c’est-à-dire qu’il existe pour dire aux clients ce qu’ils peuvent faire avec les instances, plutôt que de leur dire ce qu’ils ne peuvent pas faire.

7
Ingo

Une interface est destinée à être utilisée comme un «contrat» pour le monde extérieur. Si vous voulez utiliser des méthodes protégées, il vaut probablement mieux utiliser une classe abstraite (si elle est disponible en Java bien sûr) . Wiki

En outre, cet article contient probablement d'excellentes réponses: Pourquoi ne puis-je pas avoir de membres d'interface protégés?

4
Jan_V

Je fortement pense que les interfaces devraient permettre des méthodes protégées; qui a dit que les interfaces doivent être visibles pour tous dans le monde entier? Pour ce qui est de votre remarque, cela pourrait confondre les programmeurs "ordinaires" (lire: incompétents): Une bonne part de OOP consiste à structurer correctement les objets, les classes, les paquetages, etc., si un programmeur a du mal à faire tout cela correctement , il a un problème beaucoup plus gros. Java était construit pour ce genre de chose.

4
IntelliData

Puisqu'une classe d'implémentation doit implémenter TOUTES les méthodes déclarées dans votre interface, que se passerait-il si votre classe d'implémentation se trouvait dans un package différent?

3
dm76

Interface Si vous souhaitez utiliser quelque chose comme ce que vous avez décrit, continuez avec des classes abstraites ou des interfaces imbriquées.

Un extrait de Code Style à propos des variables d'interface, mais s'applique toujours aux méthodes bien que:

Les variables d'interface sont implicitement publiques car les interfaces sont conçues pour fournir une interface de programmation d'application (API) entièrement accessible aux programmeurs Java pour référence et implémentation dans leurs propres applications. Puisqu'une interface peut être utilisée dans des packages Java différents des leurs, la visibilité publique garantit que le code de programme peut accéder à la variable .
2
grizzly

Les méthodes protégées sont toujours accessibles par sous-classe uniquement si la sous-classe étend la classe de base.

En cas d'interface, la sous-classe ne prolonge jamais l'interface. Il implémente l'interface.

Les méthodes protégées sont accessibles via extend et non avec Implement

2
Aftaab Siddiki

Déclarer des sous-interfaces internes est une bonne pratique, mais vous ne pouvez pas déclarer techniquement vos méthodes internes en tant que protected dans une interface en Java.

Bien entendu, vous pouvez créer une autre interface à usage interne qui étend l’interface publique:

public interface YourPublicInterface {

    public void doThing1();

    public void doThing2();

    public void doThing3();

    interface Internal extends YourPublicInterface {

        void doAnyInternalThing1();

        void doAnyInternalThing2();

    }

}

Vous pouvez utiliser l'interface Internal à l'intérieur du paquet, mais vous devez accepter n'importe quel sous-type de YourPublicInterface (dans les méthodes publiques):

public class AClassInYourPackage {

    public void someMethod(YourPublicInterface param) {
        if (param instanceof YourPublicInterface.Internal) {
            // run the optimized code
        } else {
            // run the general code
        }
    }

}

En dehors du paquet, les utilisateurs peuvent utiliser YourPublicInterface sans problèmes.

Dans la pratique générale, les programmeurs créent des classes abstraites dans des situations similaires. Cependant, dans ce cas, nous perdons les avantages de l'héritage multiple.

1
Dávid Horváth

Le seul scénario où cela aurait du sens serait quand vous voulez limiter la visibilité au même paquet. Toutes les autres utilisations de protected ne sont pas applicables. Plus précisément, les méthodes protected sont souvent utilisées pour fournir un accès à certains détails d'implémentations de niveau inférieur pour les descendants. Mais déclarer cela dans une interface n'a pas de sens, car il n'y a pas d'implémentation de niveau inférieur à exposer.

Et même le scénario de paquetage n’est pas vraiment ce que sont les interfaces.

Pour obtenir ce que vous voulez probablement, vous avez besoin de deux interfaces, une à usage interne et une à exposer dans l'API publique. (Avec l’interne éventuellement, mais pas nécessairement l’extension du public.) Ou, comme d’autres l'ont fait remarquer, une superclasse abstraite.

1
biziclop

Bonne question, si la question était de savoir pourquoi les développeurs ont rendu les attributs d'interface publics non protégés, ...?

Autoriser protected aurait violé la politique/propriété de l'interface, "quelle que soit l'abstraction que vous fournissez, elle devrait être accessible partout sans condition, mais ne devrait pas permettre de la modifier. (Ex: valeur de instance var)"

Pour servir ce type de cas d'utilisation, vous devriez éviter d'utiliser l'interface.

0
user3234777

Les interfaces sont destinées à exposer des méthodes au monde extérieur. Ainsi, ces méthodes sont publiques par nature. Toutefois, si vous souhaitez introduire abstraction au sein de la même famille de classes, il est possible de créer un autre niveau d’abstraction entre votre interface et la classe d’implémentation, c’est-à-dire une classe abstraite. Un exemple est présenté ci-dessous.

public interface MyInterface {
    public void publicMethod(); // needs to be public
}

public abstract class MyAbstractClass implements MyInterface {
    @Override
    public void publicMethod() {
        protectedMethod(); // you can call protected method here
        // do other stuff
    }
    protected abstract void protectedMethod(); // can be protected
}

public class MyClass extends MyAbstractClass {
    @Override
    protected void protectedMethod() {
        // implement protected method here, without exposing it as public
    }
}
0
Stefanos Kargas