Les attributs private eu public

Fermé
red1adn1 Messages postés 8 Date d'inscription lundi 21 mai 2018 Statut Membre Dernière intervention 20 mai 2020 - 30 août 2019 à 10:04
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 - 31 août 2019 à 15:49
Bonjour,

quelle est la différence entre un attribut public et privé si l'on peut accéder à ce dernier via des getters et setters. Je ne vois pas la différence.

Merci d'avance.

3 réponses

Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
Modifié le 31 août 2019 à 14:26
Bonjour

L'utilité des attributs privés est toujours ambiguës pour moi !!


La programmation objet s'inspire de la vie réelle, donc peut-être que des exemples de la vie réelle te feront comprendre.

Commençons par toi et moi, si ton coeur est public je peux décider quand tu m'agaces de l'arrêter. Pas cool. Le coeur est essentiel au fonctionnement de l'objet "Humain", il est donc protégé. On ne peut pas y accéder directement, un getter permet de savoir si le coeur bat en posant un doigt sur la carotide.
Un setter permet de tenter de le relancer en faisant un massage cardiaque. Mais toutes les autre interactions sont privées. C'est un peu ce que Thibault dit avec la variable qui ne doit pas valoir 0, le coeur ne peut être arrêté.

Aussi, entre un homme et une femme, malgré les différences physiologiques la méthode "Uriner" existe et s'utilise pareil, c'est son fonctionnement privé qui est différent, c'est un peu ce que dit KX (bonjour au passage) quand il parle d'héritage et de polymorphisme.

Un autre exemple, quand tu conduis une voiture, pour changer un rapport de vitesse, tu ne vas pas ouvrir la boite de vitesses et déplacer avec tes petits doigts les engrenages. Du même pour accélérer, ce n'est pas toi qui ouvres le carburateur un peu plus. Non tu te sers des pédales et du levier, se sont les setters et les getters. Non seulement c'est bien plus simple d'accès, mais il ne faut pas être un génie de la mécanique pour conduire une voiture.
Et puis imaginons, que je décide de faire modifier mon moteur pour utiliser du GPL à la place de l'essence, et bien, les pédales et le levier n'ont pas changé et l'action dessus, reste identique pour le conducteur.
Ce qui se traduit par exemple, par le fait qu'un codeur spécialisé en transaction bancaire, peut fournir un objet complexe, mais simple d'utilisation, à un autre codeur spécialisé en interface graphique et à eux deux ils construisent une appli pour téléphone portable. Et quand la banque change de protocole, des algorithmes privés de l'objet bancaire sont mis à jour mais ça ne change rien à son utilisation et donc son intégration dans l'interface.






2
red1adn1 Messages postés 8 Date d'inscription lundi 21 mai 2018 Statut Membre Dernière intervention 20 mai 2020
31 août 2019 à 14:44
Merci beaucoup !
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
31 août 2019 à 14:58
De rien
0
Thibaut63 Messages postés 123 Date d'inscription dimanche 10 août 2008 Statut Membre Dernière intervention 27 janvier 2021 40
30 août 2019 à 10:53
Concrètement l'utilisation d'attributs privés avec des get et set de manière systématique n'a pas de réelle utilité technique qu'en fonction des cas d'utilisations.
Par contre, d'un point de vu clarté, interopérabilité, ré-utilisabilité, modularité, sécurité, ça a une réelle plus-value.

Imagine que tu travailles depuis des mois sur ton code et que tu t'en rends compte qu'à chaque modification d'une variable "toto" , tu dois finalement vérifier qu'elle est différente de 0.
Là tu regardes ton code et tu vois que tu as utilisés 500 fois "toto" dans ton code...
Tu vas modifier les 500 lignes de code où ton code utilise "toto" ?
Alors que tu aurais juste à modifier le setter de "toto" et c'est réglé !

Il y a plein d'autres raisons d'utiliser ce principe d’encapsulation qui résulte de l'expérience de nombreux développeurs.

1
red1adn1 Messages postés 8 Date d'inscription lundi 21 mai 2018 Statut Membre Dernière intervention 20 mai 2020
30 août 2019 à 11:16
la vérification peut être faite sur toto (déclarée public ) depuis une méthode. Je pense que j'ai compris ce que vous voulez mais je n'arrive toujours pas à voir l'utilité des variables privées
0
red1adn1 Messages postés 8 Date d'inscription lundi 21 mai 2018 Statut Membre Dernière intervention 20 mai 2020
30 août 2019 à 11:24
Merci beaucoup
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
31 août 2019 à 12:51
Bonjour,

Il y a plein de raisons qui font qu'il est mieux d'utiliser des méthodes plutôt que les attributs.

1) Tu fais un héritage
class Fille extends Mere
, tu peux surcharger les getter et setter de la classe mère avec une implémentation spécifique de la classe fille, pour pointer sur un attribut de la classe fille en ignorant celui de la classe mère. Avec le polymorphisme tu penseras utiliser toujours le même getter mais en fait ce sera une version optimisée.
2) Un peu le même principe mais avec une
class Classe implements Interface
, tu déclares les getter et setter dans l'interface, quelque soit l'implémentation de la classe et la manière dont sont gérés les attributs, les getter et setter devront être implémentés, donc en travaillant sur l'interface tu auras accès aux méthodes sans avoir à connaître les attributs.
3) Parlons cohérence des données, parfois deux attributs sont liés l'un à l'autre, c'est le cas par exemple des attributs "size" ou "length" qui décrivent un conteneur (listes, tableaux, etc.) qui sont fortement liés à leur attributs de données "data". Si leurs attributs étaient accessibles on pourrait modifier les données (en ajouter ou supprimer) directement, mais on oublierait de modifier la taille des données correspondantes. Il est bien mieux de cacher ces attributs et de donner accès uniquement à des méthodes qui vont à chaque fois modifier les deux attributs en même temps de manière cohérente.
4) Une exception, où l'on pourra privilégier l'attribut et se passer des getter, c'est dans le cas très particulier des attributs
final
d'une classe immutable (qui n'a pas de setter). Dans ce cas aucune altération des données ne pourra être effectuée donc l'accès vers les getter peut être superflu, même si en général on implémentera quand même le getter par cohérence dans l'API.
5) Tu utilises sûrement un IDE pour coder (Eclipse, IntelliJ...), il est très pratique quand on manipule un objet qu'on ne connait pas de pouvoir faire "x.get" et de laisser l'IDE lister tous les getter auxquels on a accès.
0
red1adn1 Messages postés 8 Date d'inscription lundi 21 mai 2018 Statut Membre Dernière intervention 20 mai 2020
31 août 2019 à 13:38
Merci beaucoup pour tous ces exemples !! J'ai bien compris ce que tu voulais dire sauf que les getters et setters sont des méthodes qui nous permettent de contrôler des attributs et qu'on peut les appliqués sur des attributs publiques . Je comprend mtn leurs utilité mais je ne vois pas celle des attributs privés.
L'utilité des attributs privés est toujours ambiguës pour moi !!
Sinon merci beaucoup.
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015 > red1adn1 Messages postés 8 Date d'inscription lundi 21 mai 2018 Statut Membre Dernière intervention 20 mai 2020
31 août 2019 à 15:49
"sauf que les getters et setters sont des méthodes qui nous permettent de contrôler des attributs et qu'on peut les appliqués sur des attributs publiques"
Non, tu peux les appliquer sur n'importe quels types d'attributs, en particulier les attributs privés.
Si tu contrôles les attributs via les méthodes, tu perds ce contrôle en laissant les attributs publics en laissant la possibilité à faire des actions directes sans passer par les méthodes de contrôles.

Exemple ultra classique, un attribut ne doit jamais être null, si le setter prends en paramètre une valeur null alors on lève une exception, de manière à s'assurer qu'avec l'appel à un getter on n'ait jamais null.

/**
 * Conteneur d'objet non null.
 * 
 * @author KX
 *
 * @param <E> le type de la valeur
 */
public class NotNull<E> {

    /** une valeur non null */
    private E notNullValue;

    /**
     * Constructeur d'une valeur non null.
     * 
     * @param notNullValue une valeur non null
     * @throws IllegalArgumentException si la valeur est null
     */
    public NotNull(E notNullValue) {
        setNotNullValue(notNullValue);
    }

    /**
     * Modifie la valeur.
     * 
     * @param notNullValue une valeur non null
     * @throws IllegalArgumentException si la valeur est null
     */
    public final void setNotNullValue(E notNullValue) {
        if (notNullValue == null) {
            throw new IllegalArgumentException("La valeur ne doit pas être null");
        } else {
            this.notNullValue = notNullValue;
        }
    }

    /**
     * Récupère la valeur
     * 
     * @return la valeur (ne peut jamais être null)
     */
    public final E getNotNullValue() {
        return notNullValue;
    }
}

Exemple d'utilisation :
public static void main(String[] args) {
    NotNull<String> notNullString = new NotNull<>("Hello");
    System.out.println(notNullString.getNotNullValue()); // "Hello"
    notNullString.setNotNullValue(null); // IllegalArgumentException
}

Maintenant, considérons que tu ais laissé l'attribut public, je pourrais faire ceci :
notNullString.notNullValue = null;

Ta classe ne sert plus à rien, son seul intérêt repose sur le contrôle effectué par le setter mais n'importe qui peut court-circuiter ces contrôles en modifiant directement les attributs...
0