Pourquoi n'y a-t-il pas de modificateur d'accès «sous-classes uniquement» en Java?


16

En Java, il existe quatre modificateurs d'accès disponibles pour les méthodes:

public - n'importe quelle classe peut utiliser cette méthode.

protected - les classes du même package et les sous-classes de n'importe quel package peuvent utiliser cette méthode.

private - seule cette classe peut utiliser cette méthode.

no modifier ("package private") - seules les classes du même package peuvent utiliser cette méthode.

Ce qui arrive souvent, c'est que je veux avoir des méthodes utiles dans une superclasse, que toutes les sous-classes peuvent utiliser. Mais cela n'aurait aucun sens pour les autres classes d'accéder à cette méthode, et dans un sens, cela briserait l'encapsulation.

Je dois donc déclarer ces méthodes utiles dans la superclasse publicou protected, ce qui les expose à toutes les autres classes au moins dans le package. Même s'ils ne sont destinés qu'à être utilisés par les sous-classes.

Y a-t-il une raison pour laquelle il n'y a pas de subclasses-onlymodificateur d'accès en Java? Cela me semble très étrange. Suis-je en train de manquer quelque chose?

En outre, un subclasses-onlymodificateur d'accès serait également utile lorsque vous souhaitez exposer des variables uniquement à des sous-classes. Ce qui m'arrive souvent.

Réponses:


10

Parce que vous pouvez émuler le modificateur de sous-classes uniquement en utilisant le modificateur protégé et en imposant que seules la classe parente et ses sous-classes se trouvent dans le même package.

C'est en effet une bonne pratique, car les packages aident non seulement à organiser de grands projets en termes de cohésion, mais ils montrent également que les classes du même package peuvent avoir un certain niveau de couplage.


15
"et en faisant en sorte que seules la classe parente et ses sous-classes soient dans le même paquet" - Maintenant, comment faire cela?!
JimmyB

1
Et puis, vous ne pouvez pas utiliser le modificateur d'accès au package uniquement. Et vous avez besoin d'une quantité stupide de paquets. Ce n'est pas une solution pratique.
user253751

13

Java avait à l'origine un tel modificateur. Il a été écrit private protectedmais supprimé en Java 1.0.

Je suppose que c'était un jugement que la complexité supplémentaire ne valait pas le coût.

Chaque fonctionnalité de langage a un coût: en l'enseignant aux nouveaux programmeurs; dans la documentation; en l'implémentant dans le compilateur, la JVM et les outils de développement; dans le raisonnement sur l'exactitude du programme; en contraignant l'évolution future du langage; et plus. Les fonctionnalités du langage interagissent entre elles, potentiellement avec des interactions N 2 .

Quel pourcentage des programmeurs Java ont lu la spécification du langage Java et la spécification VM? Je parie que c'est un petit pourcentage, ce qui plaide pour un langage encore plus simple dans un souci de compréhension et de produits d'ingénierie sur lesquels nous pouvons compter

L'avantage de la private protectedfonctionnalité était faible car le package est l'unité principale de modularité.


1
donc il y avait une version Java avant 1.0?
Mark Yisri

1
@MarkYisri Java a eu des versions publiques alpha et bêta en 1995, et un bon bout de code a été écrit contre elles.
David Moles

4

Le contrôle d'accès peut être considéré comme le résultat d'une couverture avec un développeur imaginaire qui travaille avec votre classe sur les méthodes et les propriétés de la classe ...

VOUS: Disons que vous voulez faire x, vous appelez la méthode doX .. DEV: Dites-moi plus .. quels sont les arguments?

C'est public ...

VOUS: À l'intérieur de doX j'appelle ... DEV: Whoa, trop d'informations, je m'en fiche. Je veux juste savoir comment l'utiliser. Dis moi quelque chose d'autre.

C'est privé ...

VOUS: Lors de la sous-classe, j'ai doX et doY appelez doIt qui le fait .. DEV: Oui, je vais sous-classe, dites-moi plus ...

C'est protégé ...

VOUS: Je pars en vacances dans une heure, je serai parti pour les 6 prochains mois. Le patron dit que ce chiot est le vôtre! Au revoir. DEV: Attends n'y vas pas encore, dis-moi tout ...

Ceci est un package.

VOUS: La méthode doItWhen n'est appelée que par cette classe et elle n'a pas changé depuis dix ans. Il ... DEV: Whoa, nous sommes à 50 minutes. Propriété suivante, et parlez plus vite.

C'est protégé privé ...


3

Cela existe déjà. Il est protégé.

Vous avez le contrôle sur les classes qui existent dans le package. S'il n'y a pas d'autre classe dans le package et qu'une variable ou une méthode donnée est protégée, il s'agit de "sous-classes uniquement".

Cela dit, encore une fois, vous avez le contrôle sur les classes qui existent dans le package. Vous pouvez choisir de ne tout simplement pas utiliser les méthodes ou variables protégées.


3
En dehors de certains packages système réservés, ne puis-je ajouter une classe à aucun package, même l'un des vôtres auquel vous ne comptez pas que j'ajoute des classes?
David Moles

@David IIRC oui, mais il ne vous permettra pas d'accéder aux champs du package à partir d'un autre JAR, donc même si vous le mettez dans le même package, s'il se trouve dans un autre JAR, vous ne pouvez pas y accéder. Cependant, si vous faites référence au même JAR, alors oui, vous pouvez y accéder, mais si vous êtes en mesure de modifier le JAR en question, vous pouvez tout aussi facilement changer le modificateur d'accès.
Pokechu22

1
@ Pokechu22 Je pense que vous devez sceller le JAR pour obtenir cette protection, mais bon point.
David Moles
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.