9
votes

Comment encapsuler un tableau en Java

Je commence avec Java et j'apprends des ensembles, des getters et de l'encapsulation. J'ai un programme très simple, deux classes:

  • conteneur a un tableau Int privé ( numarray ) avec son setter & getter.

  • principale crée un objet objet et l'utilise dans totalacarray méthode.


    xxx

    Problème: Je peux changer le tableau INT privé via le getter, je sais que c'est parce que getnumarray renvoie une référence à numarray , pas le tableau lui-même. Si j'étais intéressé par un seul élément de la matrice, je ferais un getter avec une valeur d'index, mais je souhaite toute la matrice pour la méthode TotalArray .

    Comment puis-je empêcher numarray d'être modifié de sa classe?


0 commentaires

8 Réponses :


3
votes

Généralement, vous examineriez l'interface que vous essayez de fournir aux appelants de votre classe.

méthodes telles que: xxx

sont le genre de choses que vous voudriez fournir dans votre classe de conteneurs. Ils interagissent ensuite avec la matrice privée sur le nom de l'appelant.

Si vous souhaitez renvoyer l'ensemble de la matrice sans permettre de modifier les modifications que vous avez pu copier le tableau dans une nouvelle et renvoie la copie.

par ailleurs, si vous utilisez les classes de collection Java au lieu du tableau primitif ils fournissent une méthode unmodifiableXXX () (par exemple Collections.unmodifiableList (myList) ) qui fournissent une lecture seule enveloppe autour de la collection.


3 commentaires

Veuillez corriger vos noms de méthodes. Les méthodes Java commencent par des lettres minuscules et l'objet sont une classe (majuscules).


Merci, c'est ce qui se passe lorsque vous passez une journée à regarder c # ...;)


+1: encapsuler votre tableau par ne pas exposer l'existence de la matrice du tout ! Faites que le conteneur dispose d'une interface riche qui représente des fonctions réelles de cette classe, plutôt que de simplement renvoyer ses membres de données internes aux appelants à faire avec leur souhait.



10
votes

Tout ce que vous pouvez faire pour empêcher que les personnes de modifier votre réseau consiste à en fournir une copie de celui-ci dans le getter.

public int[] getArray() {
    return Arrays.copyOf(numArray, numArray.length);
}


1 commentaires

«Certains» comme dans la bibliothèque Java standard.



6
votes

Si vous souhaitez retourner un tableau, vous le cloneriez:

  public int[] getArray() {
       return (int[]) numArray.clone();
  }


0 commentaires

1
votes

Encapsulation est le processus de cacher la mise en œuvre. Si la collection stocke ses données dans un tableau ou non est un détail de mise en œuvre; S'il était encapsulé, vous voudriez pouvoir le modifier à un autre type de stockage.

Le fait même que vous exposez à l'état (ou à l'état dérivé) lorsque les getters et les setters enfreignent l'encapsulation et implique que vous mettez en place un type de données abstrait plutôt qu'une véritable classe orientée objet. Par exemple, un (code> ArrayList est un type de données qui ne représente pas une véritable encapsulation de comportement dans une application. Si c'est ce que vous voulez dépend de la manière dont le type doit être utilisé.

Je aurais tendance à créer conteneur implémenter itéroureux pour une intervention externe s'il s'agit simplement d'un type de données de conteneur, ou fournissez une méthode d'itérateur interne à laquelle vous Passez un visiteur s'il était destiné comme une classe encapsulée. S'il s'agit d'un type de données abstraite, envisagez vivement d'utiliser les celles intégrées telles que int [] ou Liste


0 commentaires

0
votes

Il y a encore une autre façon, qui ne fait pas une copie du tableau, mais a d'autres inconvénients. Je l'utiliserais pour de très grands tableaux: xxx


0 commentaires

0
votes

Je voudrais suggérer une approche différente de toutes les réponses que j'ai vues ici. C'est pratique lorsque vous envisagez d'encapsulation de penser également à la règle "Ne demandez pas à un objet pour ses données, demandez à un objet de fonctionner sur ses données pour vous".

Vous ne m'avez pas donné une utilisation pour numarray , je vais prétendre que votre cible était de créer un "vecteur" numérique à partir de mathématiques (pas de vecteur Java) par exemple. < / p>

Vous créez donc une classe numericvector qui contient un tableau de doubles. Votre NumericVector aurait des méthodes telles que multiplierbyscalar (double scalaire) et addveur (secondvector secondvector) pour ajouter des éléments.

Votre matrice interne est complètement encapsulée - elle ne s'échappe jamais. Toute opération effectuée sur celle-ci est effectuée dans votre classe NumericVector via ces "méthodes commerciales". Comment l'afficher-vous après avoir fonctionné dessus? Avoir Numericvector remplacer numericvector.tostring () de sorte qu'il imprime correctement ou si vous avez une interface graphique, écrivez une classe "contrôleur" pour transférer des données de votre modèle (numérosicvector) à votre vue (GUI). Cela peut nécessiter un moyen de diffuser des éléments de votre numericvector.

Cela indique également quelques éléments à éviter: Ne créez pas automatiquement des setters et des getters, ils brisent votre encapsulation. Vous avez souvent besoin de getters mais, comme les autres ici l'ont dit, vous devez rendre votre getter retourner une version immuable de la matrice. Essayez également de rendre vos cours immuables dans la mesure du possible. Cette méthode que j'ai mentionnée précédemment numericvector.addvector (NumericVector secondvector) ne doit probablement pas modifier numericvector mais renvoyer un nouveau numericvector avec la solution.

Le cas où cela (et oo en général) échoue souvent est des bibliothèques - lorsque vous vraiment souhaitez ajouter une petite fonctionnalité à votre tableau, mais le laissez toujours comme une matrice à usage général. Dans ce cas, Java ne se soucie généralement pas d'encapsulation du tout, il ajoute simplement une méthode / classe d'assistance pouvant faire des choses à la collecte / matrice (regarder l'objet "tableaux" pour un tas de grands exemples).


0 commentaires

0
votes

Comment encapsuler un tableau en Java

La question peut être suffisamment claire, mais je suppose que le point de oop est de concevoir une classe comme une entité qui manipule ce tableau et extrait sa propre API. < / p>

Si vous persistez, retournez un clone de la table (forte> / copie défensive est la voie à suivre pour des cas simples .


0 commentaires

0
votes

Un moyen efficace de mémoire de la mémoire est ... XXX

Ceci permet au immutablelist de définir le nombre correct d'éléments dans le tableau de support de la table de support Code> Liste et réduit le nombre d'objets intermédiaires créés.


0 commentaires