J'essaie de comprendre beaucoup de fois mais je n'ai pas compris cela.
L'encapsulation est la technique permettant de rendre les champs d'une classe privés et de fournir un accès aux champs via des méthodes publiques. Si un champ est déclaré privé, il ne peut être consulté par personne en dehors de la classe, masquant ainsi les champs de la classe.
Comment pouvons-nous changer les valeurs des champs à l'aide de méthodes de définition? Comment empêchons-nous d'accéder directement aux champs? Quel est le véritable usage de l'encapsulation?
Supposons que vous avez une propriété age
.
L'utilisateur peut entrer la valeur -10
, qui est un âge valide, bien que valide. Une méthode de définition pourrait avoir une logique qui vous permettrait d'attraper de telles choses.
Un autre scénario serait d’avoir le champ age
, mais de le cacher. Vous pouvez aussi avoir un champ Date de naissance, et dans son setter vous aurez quelque chose comme ceci:
...
private int age
private Date dob
...
public void setDateOfBirth(Date dob)
{
this.dob = dob;
age = ... //some logic to calculate the age from the Date of Birth.
}
Je suis aussi confus que vous aussi depuis longtemps, jusqu'à ce que je lise le livre Encapsulation et héritage dans un langage de programmation objet-orienté et un site Web expliquant l'importance de l'encapsulation. En fait, le site Web m'a dirigé vers le livre.
Les gens disent toujours que l’encapsulation est une "dissimulation d’informations" donc peut-être, faisant de l’encapsulation l’accent mis sur la sécurité comme principale utilisation. Oui, vous cachez des informations dans la pratique, mais cela ne devrait pas être la définition, car cela pourrait confondre les gens.
L'encapsulation consiste simplement à "minimiser les interdépendances entre modules écrits séparément en définissant des interfaces externes strictes" (citation tirée du livre). C'est-à-dire que lorsque je construis un module, je souhaite un contrat strict entre mes clients et moi sur la manière dont ils peuvent accéder à mon module. La raison en est que pour que je puisse améliorer le fonctionnement interne sans que cela affecte le client, la vie, l'application ou tout ce pour quoi il utilise mon module. Parce que leur "module" ne dépend pas exactement du fonctionnement interne de mon module mais dépend de "l'interface externe", je les ai mis à leur disposition.
Donc, si je ne fournis pas de setter à mon client et que je leur donne un accès direct à une variable, et je réalise que je dois définir une restriction sur la variable avant que mon client puisse l'utiliser, je peux le changer, cela pourrait être moi, changer la vie de mon client, ou l'application de mon client avec des dépenses énormes. Mais si je fournissais le "contrat strict" en créant une "interface externe stricte", c'est-à-dire un configurateur, alors je pourrais facilement changer mon fonctionnement interne avec très peu ou pas de frais pour mes clients.
Dans la situation du setter (en utilisant l'encapsulation), s'il arrive que vous définissiez une variable et que je vous renvoie un message l'informant de son affectation, je pourrais maintenant envoyer un message via mon "interface", informant mon client du nouveau c’est-à-dire que vous ne pouvez pas attribuer de nombres négatifs, c’est-à-dire si mes clients essaient d’attribuer un nombre négatif. Mais si je n’utilisais pas l’encapsulation et si je donnais à mon client un accès direct à une variable et que j’apportais mes modifications, cela pourrait entraîner un plantage du système, car, si la restriction que j’implaisais, c’est que vous ne pourriez pas enregistrer les négatifs et mon client. mes clients auront toujours un système en panne (si ce "système en panne" était un système bancaire, imaginez ce qui pourrait se passer).
Ainsi, l'encapsulation consiste davantage à réduire la dépendance entre les modules, de sorte que l'amélioration peut être faite "de manière discrète" avec peu ou pas de frais pour les autres modules qui l'interagissent, plutôt que de sécurité. Parce que les modules en interaction dépendent de "l'interface externe stricte ou du contrat strict".
J'espère que cela l'explique correctement. Sinon, vous pouvez aller sur les liens ci-dessous et lire par vous-même.
Encapsulation et héritage dans les langages de programmation orientés objet
L'utilisation réelle de l'encapsulation réside également dans le fait que vous pouvez effectuer des contrôles/traitements supplémentaires sur la manière dont les valeurs sont définies.
Vous n'empêchez pas l'accès aux champs, vous contrôlez comment d'autres peuvent accéder à certains champs. Par exemple, vous pouvez ajouter une validation à votre méthode de définition ou vous pouvez également mettre à jour un autre champ dépendant lorsque la méthode de définition d'un champ est appelée.
Vous pouvez empêcher l'accès en écriture ou en lecture au champ (par exemple, en fournissant uniquement un getter ou un setter, respectivement) - mais l'encapsulation avec des propriétés vous permet de faire plus que cela.
Tout ce que je suis capable de changer les valeurs des champs à travers des méthodes de définition.
Seulement si la méthode setter vous permet de le faire.
Comment nous empêchons les champs d'accès?
Le passeur et le getter contrôlent si et comment vous pouvez accéder aux champs.
Un passeur peut vérifier si la valeur est valide. Il peut demander à SecurityManager si vous devez être autorisé à le faire. Il peut convertir entre les types de données. Etc.
Si vous avez des champs privés auxquels ils ne peuvent pas accéder en dehors de la classe, cela signifie que ces champs n'existent pas pour le monde extérieur et oui, vous pouvez changer leur valeur à l'aide de méthodes de définition, mais en utilisant des méthodes de définition, vous avez plus de flexibilité/contrôle qui peut changer les champs et à quelle valeur peuvent-ils être changés en ... essentiellement avec l’encapsulation, vous devez imposer des restrictions sur le mode et les personnes qui changent vos champs. Par exemple, vous avez: un salaire double privé, vous définissez Cette méthode pourrait limiter le fait que seul le personnel de RH peut modifier le champ de traitement, ce qui pourrait être écrit ainsi:
void setSalary(Person p,double newSalary)
{
//only HR objects have access to change salary field.
If(p instanceof HR && newSalary>=0)
//change salary.
else
S.o.p("access denied");
}
Imaginez si le salaire était public et pouvait être directement accessible, tout le monde pouvait le changer quand et quand ils le voulaient, c’est là l’importance de l’encapsulation.
Encapsultaion est utilisé pour masquer les variables membres, en rendant membre privé et en accédant à cette variable membre par les méthodes getter et setter.
Exemple
classe Encapsulation {
private int value ;
Encapsulation() {
System.out.println("constructor calling ");
}
void setValue(int value){
this.value = value;
}
int getValue() {
return value;
}
} class EncapsulationMain {
public static void main(String args[]) {
Encapsulation obj = new Encapsulation();
obj.setValue(4);
//System.out.print("value is "+obj.value);
//obj.value = 55;
//System.out.print("obj changing the value"+obj.value);
System.out.print("calling the value through the getterMethod"+obj.getValue());
}
}
vous ne pouvez pas accéder à la valeur privée en dehors de la classe.
Supposons que vous créiez une classe de date personnalisée avec les setters/getters suivants:
getDay()
getMonth()
getYear()
setDay()
setMonth()
setYear()
En interne, vous pouvez enregistrer la date en utilisant:
private int day;
private int month;
private int year;
Ou vous pouvez stocker la date en utilisant un objet Java.lang.Date:
private Date date;
L'encapsulation n'expose pas le fonctionnement interne de votre classe. Cela vous donne plus de liberté pour changer le fonctionnement de votre classe. Cela vous donne la possibilité de contrôler l'accès à votre classe. Vous pouvez vérifier si ce que l'utilisateur a entré est valide (vous ne voulez pas que l'utilisateur entre un jour avec une valeur de 32).
L'idée principale derrière l'encapsulation est la dissimulation de données. Nous utilisons l'encapsulation dans la programmation orientée objet pour plusieurs raisons. Certaines des raisons identifiées de l’encapsulation sont les suivantes ( L’utilisation réelle de l’encapsulation ).
Meilleure facilité de maintenance : Lorsque toutes les propriétés sont privées et encapsulées, il est facile pour nous de maintenir le programme simplement en modifiant les méthodes.
Facilitez le débogage : Cela correspond au point ci-dessus. Nous savons que l'objet ne peut être manipulé que par des méthodes. Cela facilite donc le débogage et la correction des bogues.
Avoir un environnement contrôlé : Permet aux utilisateurs d’utiliser les objets donnés, de manière contrôlée, à travers des objets.
Masquer les complexités : Masquer les complexités sans rapport avec les utilisateurs. Parfois, certaines propriétés et méthodes sont uniquement destinées à un usage interne et l'utilisateur n'a pas à les connaître. Cela facilite l'utilisation de l'objet par l'utilisateur.
Donc, pour répondre à la question "Quelle est l'utilisation de l'encapsulation quand je suis capable de changer les valeurs de propriété avec des méthodes setter?}", Voici l'une des principales raisons pour lesquelles nous utilisons l'encapsulation. Pour fournir une compréhension sur pourquoi, les accesseurs sont utiles , voici quelques points importants obtenus de cet article .
Vous pouvez limiter les valeurs pouvant être stockées dans un champ (c’est-à-dire que le sexe doit être F ou M).
Vous pouvez prendre des mesures lorsque le champ est modifié (événement déclencheur, validation, etc.).
Vous pouvez assurer la sécurité des threads en synchronisant la méthode.
Vous pouvez basculer vers une nouvelle représentation des données (champs calculés, type de données différent)
Son objectif n'est rien mais protéger tout ce qui a tendance à changer. Vous avez beaucoup d'exemples sur le Web, je vous en présente donc certains avantages:
immutable class
en JavaL'accès aux champs via les méthodes fait la différence car cela rend la programmation orientée objet. Par exemple, vous pouvez étendre votre classe et changer le comportement que vous ne pouvez pas faire avec un accès direct. Si vous avez des getters/setters, vous pouvez créer un proxy de votre classe et effectuer un AOP ou un proxy dynamique 1.4. Vous pouvez faire une maquette de votre classe et faire des tests unitaires ...
Eh bien, l’encapsulation ne consiste pas uniquement à cacher des données. Il s’agit avant tout de contrôler ce qui est stocké dans les champs. En utilisant l'encapsulation, nous pouvons créer un champ en lecture seule ou en écriture uniquement en fonction des besoins. De plus, les utilisateurs ne savent pas comment les données sont stockées dans les champs. Nous pouvons utiliser un chiffrement spécial dans les méthodes de définition et le stocker dans les champs. Par exemple, humain est un objet. Nous demandons seulement que le champ de nom de l'humain soit lu par l'utilisateur mais ne soit pas modifié. Ensuite, nous définissons uniquement la méthode get sur le champ de nom. Voici comment l’encapsulation est utile.
Si vous avez classe, toutes ses propriétés sont privées, ce qui signifie qu'elles ne peuvent pas être accessibles de l'extérieur de la classe. Le seul moyen d'interagir avec les propriétés de la classe est d'utiliser ses méthodes publiques.
Vous modifiez ces valeurs en donnant au public l’accès à ces méthodes (setters).
en utilisant l'encapsulation, les champs d'une classe peuvent être créés read-only
ou write-only.
En utilisant l'encapsulation, vous séparez votre classe du monde extérieur (autres classes), lequel peut accéder aux variables d'instance de classe et les modifier via des modificateurs d'accès, ce qui présente plusieurs avantages:
-Vous pouvez vous connecter à vos méthodes getter/setter.
-Vous pouvez valider/normaliser (par exemple, rogner des espaces, supprimer des caractères spéciaux, ...) votre méthode de saisie dans setter.
Et vous pouvez aussi cacher votre implémentation au monde extérieur, par exemple vous avez une collection comme une liste de tableaux dans votre classe et vous écrivez votre méthode getter comme ceci
public List<t> get collection(){
return new ArrayList<t>(this.arrayList);
}
Ainsi, dans ce cas, si vous décidez à l'avenir de changer votre implémentation de la collecte d'une liste de tableaux en quelque chose comme une liste chaînée, vous êtes libre de le faire, car Out Side World ne sait rien de votre implémentation.
Au lieu de laisser tout le monde accéder aux variables directement:
public Object object;
Il est préférable d’utiliser les méthodes SET et GET ou, par exemple, uniquement la méthode GET (vous ne voulez parfois pas que personne ne définisse une autre valeur avec cette variable).
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}