Je suis un peu confus quant au terme "paquet privé" utilisé par une partie de la documentation, ainsi qu'à l'utilisation de "accès par défaut". Le paquet privé et l'accès par défaut ne sont-ils pas synonymes de protégés?
Oui, c'est presque pareil. Le modificateur protected spécifie que le membre n'est accessible que dans son propre package (comme avec package-private) et, en outre, par une sous-classe de sa classe dans un autre package.
Le modificateur d'accès "par défaut" (celui pour lequel aucun d'entre eux n'est explicitement indiqué) est "package-private", ce qui signifie que seuls les éléments du même package peuvent y accéder. Cependant, être dans le même paquet n'implique en rien la relation d'héritage entre les classes - c'est purement une convention de nommage.
"Protégé" signifie que non seulement les classes d'un même paquet, mais également les sous-classes (quel que soit le paquet dans lequel ces sous-classes se trouvent) pourront y accéder.
L'accès par défaut pour classes est package-private, cependant l'accès par défaut pour interface membres est public.
par exemple.
public interface I {
int A = 1;
// same as
public static final int A = 1;
void method();
// same as
public abstract void method();
class C { }
// same as
public static class C { }
}
Les règles d'accès par défaut pour les interfaces ne sont pas les mêmes que pour les classes.
Package-private et access default sont des synonymes. Un objet peut également accéder au membre protégé des objets dont les classes sont dans le même package. Un objet peut également accéder au membre protégé de ses super-classes sans condition sur leur package. À titre d'exemple concret:
package ab;
class A {
protected void foo() {}
void dd(){}
}
class C {
void aa(){
A a = new A();
a.foo(); //legal
a.dd(); //legal
}
}
package sub;
class D extends A{
void ac(){
foo(); //legal ..
dd(); //illegal.. because dd has default access..
}
class E {
void ee(){
A a = new A();
a.foo(); //illegal
a.dd(); //illegal
}
Le "paquet privé" et l'accès par défaut sont les mêmes. Dans les premières versions du compilateur autour de 1.1.2/3, "package" était un modificateur autorisé, mais ignoré, ce qui signifie la même chose qu’aucun modificateur, c’est-à-dire "package privé". Peu de temps après, il y eut une mode éphémère pour mettre /*package*/
(en commentaire) dans de telles situations. De même, à ce moment-là, vous pouviez déclarer des choses comme des classes synchronisées, bien qu’il n’y ait pas non plus d’effet sémantique réel.
Ni l'un ni l'autre n'est identique à 'protected', ce qui s'étend aux classes dérivées d'autres packages.
De spécification de langage Java
- 6.6.5 Exemple: champs, méthodes et constructeurs d'accès par défaut Si aucun des modificateurs d'accès public, protected ou private n'est spécifié, un membre de la classe ou constructeur est accessible dans tout le package contenant la déclaration de la classe dans laquelle le membre de la classe est déclaré, mais le membre de la classe ou le constructeur n'est accessible dans aucun autre package.
Si une classe publique a une méthode ou un constructeur avec un accès par défaut, cette méthode ou ce constructeur n'est ni accessible ni hérité par une sous-classe déclarée en dehors de ce package