question avec la visibilité de protected en java

Le problème exposé dans ce sujet a été résolu.

Bonjour j’ai découvert par hasard que ceci fonctionne:

public class Animal {
    protected String nom;
}

public class Chaton extends Animal {
    public void qqch(Animal unAnimal) {
        String test = unAnimal.nom;
    }
}

Alors ce qui me choque c’est d’avoir un accès sans Getter à un attribut protégé d’un objet indépendant de Chaton. unAnimal pourrait être un chien par exemple.

Ce qui ne me choque pas c’est ça par exemple :

public class Chaton extends Animal {
    public void qqch() {
        String test = this.nom;
    }
}

Puisque this fait bien référence à Chaton. Comment expliquer vous que le premier code compile ?

+0 -0

Déjà, un réflexe à prendre : quand on découvre un comportement bizarre relativement trivial dans un langage aussi utilisé que Java, la première chose à se dire c’est qu’on a mal compris un truc, et pas que c’est un bug.

Sinon, pour te répondre, ce que tu obtiens est un effet tout à fait normal et souvent mal compris de ce qu’impliquent les visibilités en Java. Tout est sur cette page (en anglais). Ça vient du fait que tes deux classes sont dans le même package, donc elles voient les attributs publics, package-protected et protected des autres classes du même package.

Si tu fais ceci, tu obtiens le comportement que tu imaginais avoir :

package unpackage;

public class Animal {
    protected String nom;
}

et

package un.autrepackage;


import unpackage.Animal;

public class Chaton extends Animal {
    public void qqch(Animal unAnimal) {
        String test = unAnimal.nom;
    }
}

(tu obtiens une erreur de compilation sur unAnimal.nom).

Comme le reste, c’est à utiliser quand c’est pertinent :)

Au-delà de ça, je crois qu’absolument plus personne ne comprends pourquoi la visibilité protected en Java autorise aussi la visibilité de ce qu’il y a dans le package. Ça fait partie des bizarreries historiques.

Parce que protected, c’est visible depuis le package + ce qui dérive de la classe. C’est fait pour rendre des trucs visibles par les sous classes.

On pourrait certes imaginer un contrôle plus fin que les 4 niveaux de java. Mais,

  • est-ce que ça n’embrouillerait pas le programmeur moyen ?
  • est-ce bien utile ?

Le modificateur protected accorde cette visibilité là parce que c’est défini comme ça depuis que Java existe. La réalité c’est qu’il faut faire avec, point barre.

Maintenant, la question de savoir pourquoi les concepteurs de java ont choisi de faire comme ça, plutôt que de définir un niveau d’accessibilité "privé + classes dérivées y compris en dehors du package", il faut leur demander à eux.

L’esprit général du truc, ça semble être que les gens qui travaillent à réaliser un package ne sont pas supposer se tirer dans les pattes ni faire preuve de paranoia. Quand Marcel qui bosse sur une classe ne souhaite pas que ses petits camarades utilisent sa méthode machin qui est une méthode auxiliaire et ne fait pas partie de "l’API interne du package", il la marque private, ça fait le job.

A mon avis, ça ne pose un problème que pour les débutants qui font des packages fourre-tout.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte