Méthodes d'obtention de magie PHP. Getters and Setters - une magie qui doit connaître sa place

Pour contrôler la manière dont les champs sont utilisés, vous pouvez créer obtenir des méthodes et les définir et les rendre publics. Ils offrent la possibilité de contrôler l’accès à un champ. Dans le même temps, il est préférable de rendre le champ Âge privé afin qu'il ne soit pas directement accessible en dehors de la classe.

Compte de classe publique

âge int privé ;

public int GetAge()

renvoie this.age;

public void SetAge (int inAge)

if ((inAge > 0) && (inAge< 120))

this.age = inAge;

Nous pouvons désormais contrôler l'accès à notre champ, mais cela nécessite d'écrire beaucoup de code supplémentaire. Afin d'accéder à la valeur d'âge, vous devez appeler les méthodes créées :

Compte s = nouveau compte ();

Console.WriteLine("Âge : " + s.GetAge());

    1. Utilisation des propriétés

Les propriétés facilitent la gestion des données. La propriété Age peut être déclarée comme suit :

Compte de classe publique

valeur d'âge int privée ;

si ((valeur > 0) && (valeur< 120))

âgeValue = valeur ;

renvoie la valeur d'âge ;

Ici, la valeur d'âge est une propriété. La propriété déclare des sections pour écrire et lire sa valeur. Les actions décrites dans ces sections sont équivalentes aux méthodes décrites précédemment. Dans ce cas, les propriétés sont utilisées de la même manière que les champs normaux :

Compte s = nouveau compte ();

Console.WriteLine("Âge : " + s.Âge);

Lorsque la propriété Age est définie sur une valeur, le code de section défini est appelé. Le mot-clé value indique la valeur attribuée à la propriété. Lors de la lecture de la valeur de la propriété Age, le code de la section get est appelé. Cette approche combine les avantages de l'utilisation de méthodes et vous permet de travailler avec des propriétés aussi facilement qu'avec des champs de classe.

Vérification de l'exactitude des données dans les propriétés . Si vous essayez de définir une valeur d'âge invalide (par exemple, 150), le code ci-dessus effectuera un contrôle de validité et rejettera la valeur (aucune personne de plus de 120 ans ne peut avoir de compte auprès de notre banque), laissant la valeur de vieillesse. La seule façon de savoir si une propriété a reçu une valeur est de vérifier la valeur de la propriété après cette opération :

Compte s = nouveau compte ();

int nouvelAge = 150 ;

si (s.Age != newAge)

Console.WriteLine("La valeur d'âge n'a pas été définie");

Le code suivant tente de définir l'âge sur une valeur non valide de 150, puis vérifie si cette valeur a été définie. Si la méthode Set était utilisée pour attribuer la valeur, elle pourrait renvoyer la valeur FAUX Si cela échoue, l'utilisation de la propriété nécessite que l'utilisateur effectue un peu plus de travail supplémentaire.

Différentes manières de lire la valeur d'une propriété. Les propriétés vous permettent d'effectuer d'autres actions utiles.

public int ÂgeEn Mois

renvoie this.ageValue * 12 ;

La nouvelle propriété AgeInMonths est décrite ici. Il est en lecture seule car il ne contient pas de section définie. Il renvoie la valeur d'âge en mois, en utilisant la même valeur que la propriété Age. Cela signifie que vous pouvez utiliser plusieurs de diverses façons pour obtenir la même valeur. Il est possible de créer des propriétés en lecture seule sans pouvoir les modifier directement, ainsi que des propriétés en écriture seule, bien que ces dernières soient rarement utilisées.

Propriétés des éléments visuels . Il est logique d'utiliser des propriétés dans la description d'un compte bancaire, où vous devez protéger les données des objets. Mais dans Silverlight, vous pouvez saisir n'importe quel texte dans un élément TextBlock, et il ne semble pas nécessaire de vérifier la validité de la valeur saisie. L'exécution de ce code ralentira le processus de saisie de la valeur. Ainsi, en faisant de la valeur Text une chaîne publique, le programme contiendrait moins de code et s'exécuterait plus rapidement.

Mais lorsque nous modifions le texte dans l'élément TextBlock, nous souhaitons que le texte de la page Silverlight change également, par exemple lorsque le programme Adder affiche le résultat. Si le programme modifiait simplement la valeur du champ, Silverlight n'aurait aucun moyen de savoir que le message à l'écran devait être mis à jour.

Cependant, si Text devient une propriété, lorsque la valeur de l'élément TextBlock est mise à jour, la méthode correspondante s'exécutera, qui peut mettre à jour la valeur stockée de la zone de texte et appeler une méthode pour mettre à jour l'écran afin d'afficher la nouvelle valeur. Les propriétés offrent la possibilité de manipuler un objet lorsque sa valeur change. Opération simple :

résultatTextBlock.Text = "0" ;

peut entraîner plusieurs centaines d'opérations C# car le stockage de la nouvelle valeur dans l'élément TextBlock déclenche des opérations de mise à jour de l'image d'écran.

Dernière mise à jour : 29/07/2018

En plus des méthodes classiques, le langage C# propose des méthodes d'accès spéciales appelées propriétés. Ils permettent d'accéder facilement aux champs de classe, de connaître leur valeur ou de les définir.

La description de propriété standard a la syntaxe suivante :

[access_modifier] return_type custom_name ( // code de propriété )

Par exemple:

Class Person (nom de chaîne privée; nom de chaîne publique (get (nom de retour; ) set (nom = valeur; ) ) )

Ici, nous avons un champ de nom privé et une propriété publique Name. Bien qu'ils portent presque le même nom, à l'exception du registre, ce n'est rien d'autre qu'un style ; leurs noms peuvent être arbitraires et ne doivent pas nécessairement correspondre.

Grâce à cette propriété, nous pouvons contrôler l'accès à la variable name. La définition de propriété standard contient des blocs get et set. Dans le bloc get, nous renvoyons la valeur du champ et dans le bloc set, nous la définissons. Le paramètre value représente la valeur à transmettre.

Nous pouvons utiliser cette propriété comme ceci :

Personne p = nouvelle Personne(); // Définir la propriété - le bloc Set est déclenché // la valeur "Tom" est la valeur passée à la propriété p.Name = "Tom"; // Récupère la valeur de la propriété et l'affecte à une variable - le bloc Get string personName = p.Name est déclenché ;

La question peut peut-être se poser : pourquoi avons-nous besoin de propriétés si nous pouvons nous contenter de champs de classe ordinaires dans cette situation ? Mais les propriétés vous permettent d'ajouter une logique supplémentaire qui peut être nécessaire, par exemple lors de l'attribution d'une valeur à une variable de classe. Par exemple, nous devons mettre en place un contrôle d’âge :

Classe Personne ( âge int privé ; âge int public ( ensemble (if (valeur< 18) { Console.WriteLine("Возраст должен быть больше 17"); } else { age = value; } } get { return age; } } }

Les blocs set et get ne doivent pas nécessairement être présents dans une propriété en même temps. Si une propriété est définie uniquement par un bloc get, alors la propriété est en lecture seule : nous pouvons obtenir sa valeur, mais pas la définir. À l'inverse, si une propriété n'a qu'un bloc défini, alors cette propriété est accessible en écriture uniquement - vous pouvez uniquement définir la valeur, mais vous ne pouvez pas l'obtenir :

Class Person ( nom de chaîne privé ; // propriété en lecture seule chaîne publique Name ( get ( nom de retour ; ) ) private int age ; // propriété en écriture seule public int Age ( set ( age = valeur ; ) ) )

Modificateurs d'accès

Nous pouvons appliquer des modificateurs d'accès non seulement à la propriété entière, mais également à des blocs individuels - soit get soit set :

Classe Personne ( nom de chaîne privée ; chaîne publique Nom ( get ( nom de retour ; ) ensemble privé ( nom = valeur ; ) ) personne publique (nom de chaîne, âge int) ( Nom = nom ; Âge = âge ; ) )

Nous pouvons désormais utiliser le bloc ensemble fermé uniquement dans cette classe - dans ses méthodes, propriétés, constructeur, mais pas dans une autre classe :

Personne p = nouvelle Personne("Tom", 24); // Erreur - l'ensemble est déclaré avec le modificateur privé //p.Name = "John" ; Console.WriteLine(p.Name);

Lors de l'utilisation de modificateurs dans les propriétés, il existe un certain nombre de restrictions à prendre en compte :

    Un modificateur pour un bloc set ou get peut être défini si la propriété possède à la fois des blocs set et get.

    Un seul bloc set ou get peut avoir un modificateur d'accès, mais pas les deux

    Le modificateur d'accès d'un bloc set ou get doit être plus restrictif que le modificateur d'accès d'une propriété. Par exemple, si une propriété a le modificateur public, alors le bloc set/get ne peut avoir que les modificateurs protected internal, internal, protected, private.

Encapsulation

Nous avons vu plus haut que l'accès aux variables de classe privée s'établit via des propriétés. Cacher ainsi l’état d’une classe aux interférences extérieures représente le mécanisme d’encapsulation, qui représente l’un des concepts clés de la programmation orientée objet. (Il convient de noter que le concept même d'encapsulation a de nombreuses interprétations différentes, qui ne se chevauchent pas toujours.) L'utilisation de modificateurs d'accès privés protège une variable des accès externes. Pour contrôler l'accès, de nombreux langages de programmation utilisent des méthodes spéciales, des getters et des setters. En C#, leur rôle est généralement joué par les propriétés.

Par exemple, certaines classes Account ont un champ de somme qui représente une somme :

Compte de classe (somme internationale publique ; )

Étant donné que la variable sum est publique, nous pouvons y accéder n'importe où dans le programme et la modifier, y compris en définissant toute valeur invalide, par exemple négative. Il est peu probable qu’un tel comportement soit souhaitable. Par conséquent, l’encapsulation est utilisée pour restreindre l’accès à la variable sum et la masquer à l’intérieur de la classe :

Compte de classe (somme int privée; somme int publique (get (somme de retour;) set (if (valeur > 0) (somme=valeur; ) ) ) )

Propriétés automatiques

Les propriétés contrôlent l'accès aux champs d'une classe. Cependant, que se passe-t-il si nous avons une douzaine de champs ou plus, alors définir chaque champ et écrire une propriété du même type pour celui-ci serait fastidieux. Par conséquent, des propriétés automatiques ont été ajoutées au framework .NET. Ils ont une déclaration abrégée :

Classe Personne ( chaîne publique Nom ( get; set; ) public int Âge ( get; set; ) personne publique (nom de chaîne, int âge) ( Nom = nom; Âge = âge; ) )

En fait, les champs de propriétés sont également créés ici, seulement ils ne sont pas créés par le programmeur dans le code, mais le compilateur les génère automatiquement lors de la compilation.

Quel est l'avantage des propriétés automatiques, si en substance elles accèdent simplement à une variable créée automatiquement, pourquoi ne pas accéder directement à une variable sans propriétés automatiques ? Le fait est qu'à tout moment, si nécessaire, nous pouvons étendre la propriété automobile en une propriété ordinaire et y ajouter une logique spécifique.

Il convient de considérer que vous ne pouvez pas créer de propriété automatique en écriture seule, comme c'est le cas avec les propriétés standard.

Les propriétés automatiques peuvent se voir attribuer des valeurs par défaut (initialisation des propriétés automatiques) :

Classe Personne ( public string Nom ( get; set; ) = "Tom"; public int Age ( get; set; ) = 23; ) class Programme ( static void Main(string args) ( Person person = new Person(); Console .WriteLine(personne.Name); // Tom Console.WriteLine(personne.Age); // 23 Console.Read(); ) )

Et si nous ne spécifions pas les valeurs des propriétés Name et Age pour l'objet Person, alors les valeurs par défaut s'appliqueront.

Les propriétés automatiques peuvent également avoir des modificateurs d'accès :

Classe Personne ( chaîne publique Nom ( ensemble privé; get;) personne publique (chaîne n) ( Nom = n; ) )

Nous pouvons supprimer le bloc set et rendre la propriété auto en lecture seule. Dans ce cas, pour stocker la valeur de cette propriété, un champ avec le modificateur readonly sera implicitement créé pour elle, il convient donc de prendre en compte que ces propriétés get peuvent être définies soit à partir du constructeur de classe, comme dans l'exemple ci-dessus, ou lors de l'initialisation de la propriété :

Personne de classe ( chaîne publique Name ( get;) = "Tom" )

Notation abrégée pour les propriétés

Tout comme les méthodes, nous pouvons raccourcir les propriétés. Par exemple:

Class Person ( nom de chaîne privée ; // équivalent à la chaîne publique Nom ( get ( nom de retour ; ) ) nom de chaîne publique => nom ; )

Implémentation de l'interface Ensemble est une collection non ordonnée qui ne peut pas contenir de données en double.

Interface Ensemble comprend les méthodes suivantes :

MéthodeDescription
ajouter (Objet o) Ajout d'un élément à la collection s'il est manquant. Renvoie vrai si l'élément a été ajouté.
ajouterTout(Collection c) Ajout d'éléments de collection s'ils sont manquants.
clair() Effacement de la collection.
contient (Objet o) Vérification de la présence d'un élément dans un ensemble. Renvoie vrai si l'élément est trouvé.
contientTout(Collection c) Vérification de la présence d'une collection dans un ensemble. Renvoie vrai si tous les éléments sont contenus dans l’ensemble.
est égal à (Objet o) Contrôle d'égalité.
code de hachage() Obtenir le hashCode de l'ensemble.
est vide() Vérification de la présence d'éléments. Renvoie vrai s'il n'y a aucun élément dans la collection.
itérateur() Fonction pour obtenir un itérateur de collection.
supprimer (Objet o) Supprimer un élément d'un ensemble.
supprimerTout(Collection c) Supprime tous les éléments de la collection transmise de l'ensemble.
retenirTout(Collection c) Suppression des éléments qui n'appartiennent pas à la collection passée.
taille() Nombre d'éléments de collection
versArray() Conversion d'un ensemble en un tableau d'éléments.
versTableau(T a) Conversion d'un ensemble en un tableau d'éléments. Contrairement à la méthode précédente, qui renvoie un tableau d'objets de type Object, cette méthode renvoie un tableau d'objets du type passé en paramètre.

Pour interfacer la famille Ensemble se rapporter Jeu de hachage, Ensemble d'arbres Et LinkedHashSet. En ensembles Ensemble Différentes implémentations utilisent un ordre différent de stockage des éléments. Dans HashSet, l'ordre des éléments est optimisé pour une recherche rapide. Le conteneur TreeSet stocke les objets triés par ordre croissant. LinkedHashSet stocke les éléments dans l'ordre dans lequel ils ont été ajoutés.

Ensemble de données HashSet

Constructeurs HashSet :

// Crée un ensemble vide avec une capacité initiale de 16 et un facteur de charge par défaut de 0,75 public HashSet(); // Création d'un ensemble à partir d'éléments de collection public HashSet(Collection c); // Crée un ensemble avec la capacité initiale spécifiée et // le facteur de charge par défaut (0,75) public HashSet(int initialCapacity); // Crée un ensemble avec la capacité initiale spécifiée et // le facteur de charge public HashSet(int initialCapacity, float loadFactor);

Méthodes HashSet

  • taille publique int()
  • public booléen isEmpty()
  • ajout booléen public (Objet o)
  • public booléen addAll (Collection c)
  • public booléen supprimer (Objet o)
  • public booléen RemoveAll (Collection c)
  • public booléen contient (Objet o)
  • public vide clair()
  • Clone d'objet public()
  • Itérateur public itérateur()
  • Objet public toArray()
  • public booléen RetainAll (Collection c)

Jeu de hachage contient des méthodes similaires à ArrayList . L'exception est la méthode add(Object o), qui ajoute un objet uniquement s'il est manquant. Si un objet est ajouté, la méthode add renvoie vrai, sinon faux.

Exemple d'utilisation de HashSet :

Jeu de hachage hashSet = nouveau HashSet (); hashSet.add("Pommes de terre"); hashSet.add("Carotte"); hashSet.add("Betteraves"); hashSet.add("Concombres"); // L'entrée suivante ne doit pas être dans l'ensemble hashSet.add("Potatoes"); // Imprime la taille définie sur la console System.out.println("HashSet size = " + hashSet.size()); // Imprimer les entrées de l'itérateur sur la console itr = hashSet.iterator(); while (itr.hasNext()) ( System.out.println(itr.next().toString()); )

Nous ne devrions voir que 4 entrées dans la console. Il convient de noter que l’ordre dans lequel les enregistrements seront ajoutés à l’ensemble sera imprévisible. Jeu de hachage utilise le hachage pour accélérer la récupération.

Exemple d'utilisation Jeu de hachage avec des valeurs entières. Nous ajoutons à l'ensemble des valeurs de 0 à 9 sur 25 valeurs possibles sélectionnées au hasard - il n'y aura pas de duplication.

Aléatoire aléatoire = nouveau Aléatoire (30); Ensemble iset = nouveau HashSet (); pour (int je = 0; je< 25; i++) iset.add(random.nextInt(10)); // Вывести в консоль записи Iterator

Il convient de noter que la mise en œuvre Jeu de hachage ne se synchronise pas. Si plusieurs threads accèdent simultanément à un ensemble de hachage et qu’un ou plusieurs threads doivent modifier l’ensemble, celui-ci doit alors être synchronisé en externe. Il est préférable de le faire au moment de la création pour éviter tout accès non synchronisé accidentel à l'ensemble :

Ensemble set = Collections.synchronizedSet (nouveau HashSet ());

Ensemble de données LinkedHashSet

Classe LinkedHashSet hérite Jeu de hachage sans ajouter de nouvelles méthodes, et maintient une liste chaînée des éléments de l'ensemble dans l'ordre dans lequel ils ont été insérés. Cela permet une itération ordonnée de l’insertion dans l’ensemble.

Constructeurs LinkedHashSet :

// Crée un ensemble vide avec une capacité initiale (16) et une valeur de facteur de charge par défaut (0,75) public LinkedHashSet() // Crée un ensemble à partir des éléments de la collection public LinkedHashSet(Collection c) // Crée un ensemble avec une initiale spécifiée capacité et une valeur de facteur de charge par défaut (0,75) public LinkedHashSet(int initialCapacity) // Crée un ensemble avec la capacité initiale et le facteur de charge spécifiés public LinkedHashSet(int initialCapacity, float loadFactor)

Ainsi que Jeu de hachage, LinkedHashSet ne se synchronise pas. Par conséquent, lors de l'utilisation de cette implémentation dans une application avec de nombreux threads, dont certains peuvent apporter des modifications à l'ensemble, la synchronisation doit être effectuée au stade de la création :

Ensemble set = Collections.synchronizedSet (nouveau LinkedHashSet ());

Ensemble de données TreeSet

Classe Ensemble d'arbres crée une collection qui utilise une arborescence pour stocker des éléments. Les objets sont stockés par ordre croissant.

Constructeurs TreeSet :

// Crée un ensemble d'arbres vide, trié selon l'ordre // naturel de ses éléments TreeSet() // Crée un ensemble d'arbres contenant les éléments de l'ensemble spécifié, // triés selon l'ordre naturel de ses éléments. TreeSet(Collectionc) // Crée un ensemble d'arbres vide, trié selon le comparateur TreeSet(Comparatorcomparateur) // Crée un ensemble d'arbres contenant les mêmes éléments et utilisant // le même ordre que l'ensemble trié spécifié TreeSet(SortedSet s)

Méthodes TreeSet

  • booléen ajouter (Objet o)
  • booléen addAll (Collectionc)
  • Plafond de l'objet(Objet o)
  • vide clair()
  • Clone TreeSet()
  • Comparateurcomparateur()
  • booléen contient (Objet o)
  • Itérateur descendantItérateur()
  • NavigableSet ensemble descendant()
  • Objet d'abord()
  • Sol de l'objet(Objet o)
  • Ensemble trié casque(E e)
  • NavigableSet headSet(E e, booléen inclus)
  • Objet supérieur(Objet o)
  • booléen isEmpty()
  • Itérateur itérateur()
  • Élast()
  • E inférieur(E e)
  • E sondagePremier()
  • E sondageDernier()
  • booléen supprimer (Objet o)
  • taille int()
  • Séparateur séparateur()
  • NavigableSet sous-ensemble (E fromElement, booléen fromInclusive, E toElement, booléen toInclusive)
  • Ensemble trié sous-ensemble (E fromElement, E toElement)
  • Ensemble trié tailSet (E à partir d'Element)
  • NavigableSet tailSet (E fromElement, booléen inclus)
  • Dans l'exemple modifié suivant à partir de l'utilisation Ensemble d'arbres Les valeurs seront affichées sur la console sous une forme ordonnée.

    Ensemble trié treeSet = nouveau TreeSet (); treeSet.add("Betteraves"); treeSet.add("Concombres"); treeSet.add("Tomates"); treeSet.add("Pommes de terre"); treeSet.add("Carotte"); // Cette entrée ne doit pas être incluse dans l'ensemble treeSet.add("Potatoes"); // Affiche la taille de l'ensemble sur la console System.out.println("treeSet size = " + treeSet.size()); // Imprimer les entrées de l'itérateur sur la console itr = treeSet.iterator(); while (itr.hasNext()) ( System.out.println(itr.next().toString()); ) Random random = new Random(30); Ensemble trié iset = nouveau TreeSet (); pour (int je = 0; je< 25; i++) iset.add(random.nextInt(10)); // Вывести в консоль записи Iteratoritr = iset.iterator(); while (itr.hasNext()) ( System.out.println(itr.next().toString()); )

    Joseph Crawford, l'un de mes lecteurs, a lu un article sur le fait que je n'aime pas écrire des getters et des setters et m'a suggéré d'utiliser les méthodes magiques __get et __set.
    Je vais vous expliquer pourquoi ce n'est pas une bonne idée de les utiliser de manière normale. Je vais également vous raconter une histoire où ils se sont avérés très utiles : créer des types statiques en PHP (un langage dynamique).
    Pour ceux qui ne connaissent pas les méthodes __get et __set, ce sont deux méthodes « magiques » qui fonctionnent comme ceci :
    class Animal ( function __get($property) ( //... ) function __set($property, $value) ( ​​​​//... ) ) $vache = nouvel Animal; $vache->poids = "1 tonne" ; // identique à $cow->__set("weight", "1 ton") print $cow->weight; // identique à print $cow->__get("weight");

    Généralement, les méthodes ci-dessus sont utilisées pour créer des propriétés dynamiques. Quelle conclusion peut-on en tirer ? Si vous souhaitez créer des propriétés aléatoires, utilisez simplement un hachage (c'est-à-dire un tableau avec des clés).
    Qu'est-ce qu'il y a de bien avec les getters et les setters ?
    Jetons un coup d'oeil :
    class Animal ( public $weightInKgs; ) $cow = new Animal; $vache->poidsEnKgs = -100 ;

    Quoi? Un poids négatif ? Ceci est incorrect à bien des égards.
    Une vache ne doit pas peser moins de 100 kg (je pense que oui :). Dans les 1000 est acceptable.
    Comment garantir une telle limitation ?
    Utiliser __get et __set est un moyen assez rapide.
    class Animal ( private $properties = array(); public function __get($name) ( if(!empty($this->properties[$name])) ( return $this->properties[$name]; ) else ( throw new Exception("Propriété non définie ".$name." référencée."); ) ) fonction publique __set($name, $value) ( ​​​​if($name == "weight") ( if($value< 100) { throw new Exception("The weight is too small!") } } $this->propriétés[$nom] = $valeur ; ) ) $vache = nouvel Animal; $vache->poidsEnKgs = -100 ; //lance une exception

    Que se passe-t-il si vous avez une classe avec 10 à 20 propriétés et que vous les vérifiez ? Dans ce cas, les ennuis sont inévitables.
    fonction publique __set($nom, $valeur) ( ​​if($nom == "poids") ( if($valeur< 100) { throw new Exception("The weight is too small!") } if($this->poids != $poids) ( Shepherd::notifyOfWeightChange($cow, $weight); ) ) if($name == "legs") ( if($value != 4) ( throw new Exception("Le nombre de pattes est trop petit ou trop grand") ) $this->numberOfLegs = $numberOfLegs; $this->numberOfHooves = $numberOfLegs; ) if($name == "milkType") ( .... vous voyez l'idée... .) $this->properties[$name] = $value; )

    À l’inverse, les getters et setters sont à leur meilleur en matière de validation des données.
    class Animal ( private $weight; private $numberOfLegs; private $numberOfHooves; public $nickname; public function setNumberOfLegs($numberOfLegs) ( if ($numberOfLegs != 100) ( throw new Exception("Le nombre de pattes est trop petit ou trop big"); ) $this->numberOfLegs = $numberOfLegs; $this->numberOfHooves = $numberOfLegs; ) fonction publique getNumberOfLegs() ( return $this->numberOfLegs; ) fonction publique setWeight($weight) ( if ($weight< 100) { throw new Exception("The weight is too small!"); } if($this->poids != $poids) ( Shepherd::notifyOfWeightChange($cow, $weight); ) $this->weight = $weight; ) fonction publique getWeight() ( return $this->weight; ) )

    Rien n'est comparable aux fonctions de raccourci (get, set;) de C#. Il est probable qu'un tel support apparaîtra bientôt dans PHP, mais pour l'instant ne nous détendons pas...
    Chaque méthode n'est responsable que de sa propre zone, ce qui facilite la navigation dans le code. Cela fait encore beaucoup de code, mais c'est plus propre que la version __set. Il existe une bonne approche heuristique, qui est la suivante : si votre méthode (fonction) occupe plus d'un écran, vous devez le raccourcir. Cela rendra le code plus facile à lire.
    Nous stockons également une certaine logique métier. Il y aura toujours exactement autant de sabots que de pattes, et si nous constatons un changement dans le poids du bétail, nous en informerons immédiatement le berger.
    Puisque nous ne nous soucions pas des surnoms des vaches ni ne les vérifions, laissez les données être publiques sans getters ni setters.
    Encore une fois, je n'ai pas vraiment écrit tous ces getters et setters - PHP Storm l'a fait pour moi. J'ai simplement écrit ce qui suit :
    classe Animal (privé $weight; privé $numberOfLegs; )

    Et j'ai appuyé sur Alt+Inser -> Getters et setters. PHPStorm a tout généré automatiquement.
    Désormais, comme avantage supplémentaire de PHP Storm, lorsque je travaille avec des getters et des setters, j'ai la possibilité d'utiliser la fonctionnalité de saisie semi-automatique :

    Dans le cas de __get je n'ai pas cette option, je peux seulement écrire ceci :
    $vache->poids = -100

    Maintenant, la vache « pèse » (poids) moins 100 kg.
    Je peux oublier qu'il s'agit du poids en kg, il suffit d'écrire le poids et tout fonctionnera.
    Ainsi, les getters et les setters peuvent être très utiles (mais ne les adorez toujours pas, vous n’êtes pas un programmeur Java). Si vous voulez juste des propriétés gratuites, utilisez un tableau :
    $vache = array("poids" => 100, "jambes" => 4);

    Cette astuce est beaucoup plus facile à réaliser que __get et __set.
    Mais si vous voulez être sûr que vos données n'ont toujours que des valeurs valides, utilisez des setters avec validation. Si vous disposez d'un environnement de développement intégré (IDE) comme PHP Storm, vous adorerez les setters car ils sont si faciles à utiliser. Au lieu de $cow->setLegs() pour PHP Storm il suffira de taper cosl. Oui Facile ! Il n'y a plus de fautes de frappe et vous pouvez voir quels paramètres prend la méthode.
    La méthode __set présente un autre inconvénient. Il n'accepte qu'un seul paramètre. Et s'il vous en fallait 2 ? Par exemple, comme ici : $store1->setPrice("item-1", 100). Vous devez fixer le prix du produit en magasin. La méthode __set ne vous permettra pas de faire cela, mais le setter le fera.

    mob_info