orienté objet: accéder à un attribut dans un *autre* classe

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

@Renault, j’ai relu ton message:

Mais ce n’est pas parce que de telles conditions n’existent pas encore que ces fonctions ne servent à rien. L’avantage des getter / setter c’est que l’interface externe ne bouge pas (normalement) mais le comportement interne peut évoluer. Sans les getter / setter, le moindre changement de la représentation interne t’obligera à adapter les classes qui utilisent ces propriétés directement. Avec le getter / setter, tu peux garantir une interface publique pour les autres classes tout en changeant comment cela fonctionne en interne. Ainsi si tu changes cela, les classes qui se servent de ces propriétés n’ont pas à subir des changements ou de manière mineure.

est-ce que tu pourrais me donner un exemple qui illustre la différence entre l’interface externe qui ne bouge pas et le comportement interne qui peut évoluer? ça me semble abstrait pour l’instant merci!

On peut imaginer une classe Point, avec un accès via des méthodes à ses coordonnées cartésiennes (abscisse, ordonnée) ou polaires (distance à l’origine, angle avec l’axe des abscisses). On peut changer avec des méthodes les coordonnées en donnant des coordonnées soit polaires, soit cartésiennes. Ces méthodes, c’est l’interface externe.

On a un invariant : à tout instant, les deux types de coordonnées doivent correspondre au même point.

Maintenant, on peut choisir de stocker les coordonnées cartésiennes et faire des conversions depuis ou vers les coordonnées polaires. C’est un comportement possible. Un autre comportement possible est de stocker les coordonnées polaires et convertir depuis ou vers les coordonnées cartésiennes. On peut aussi stocker les deux et d’assurer la cohérence lors de la modification.

Le différentes solutions vont avoir des performances différentes en fonction de l’utilisation d’un type de coordonnées plutôt que de l’autre, si on modifie plus souvent qu’on ne lit, etc. L’interface externe reste la même.

+0 -0

Merci, je me suis prêté à l’exercice pour voir ma compréhension…

Ci dessous le code de la classe Point. Le point est défini par ses coordonnées (x, y) qui sont privées parce que il faut s’assurer de l’invariant, à savoir que (x, y) soit exprimé en coordonnées cartésiennes.

C’est par exemple pour éviter d’écrire monPoint.y = 60.0; où 60 serait un angle polaire.

C’est pourquoi je mets à disposition de la classe Point une interface externe (càd des méthodes pour interagir avec l’objet point et ainsi le déplacer). Cette interface externe s’assure de l’intégrité de l’objet, càd que (x, y) sont bien des coordonnées cartésiennes et pas polaire.

Est ce que j’ai plus ou moins bien compris comme ça?

public class Point {
    
    // Coordonées cartésiennes du point
    private double x;
    private double y;
    
    // Le constructeur par défaut est implicite
    
    // Possibilité de déplacer le point en (x, y)
    public void moveTo(double x, double y) {
        this.x = x;
        this.y = y;
    }
    
    // Idem en coordonnées polaires (r, theta)
    public void moveTo2(double r, double theta) {
        r = Math.abs(r);
        moveTo(r * Math.cos(theta), r * Math.sin(theta));
    }
    
    // Il est possible d'avoir accès aux coordonées du point
    public double getX() {
        return x;
    }
    
    public double getY() {
        return y;
    }

    // on peut imaginer ci dessous la même mais retourner ses coordonées polaires
    // ...
}

Comme on cause de deux implémentations possible, Point pourrait être une interface commune

interface Point {
   void moveCartesien(double x, double y);
   void movePolaire(double r, double theta);
   double getX();
   double getY();
   double getModule();
   double getAngle();
}
class PointCartesien implements Point {
   ...
}
class PointPolaire implements Point {
   ...
}

Dans chacune des classes il y a 2 attributs qu’on consulte par des accesseurs, et pour les deux autres faut se farcir des calculs. bon, ok, c’est toujours un peu bidon ces exemples.

Du coup, on peut penser ajouter dans Point une méthode statique pour créer un point avec la représentation la plus appropriée au problème.

interface Point {
      static PointPolaire polaire(float module, float angle) {
          return new  PointPolaire(module, angle);
      }
      static PointCartesien cartesien(float x, float y) {
          return new  PointCartesien(x, y);
      }
      ...

et après ça s’utilisera comme ça

Point p = Point.cartesien(12.3, 45,6);
+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