1065 votes

Quelle est la différence entre public, privé et protégé ?

Quand et pourquoi devrais-je utiliser public , private y protected fonctions et variables à l'intérieur d'une classe ? Quelle est la différence entre elles ?

Exemples :

// Public
public $variable;
public function doSomething() {
  // ...
}

// Private
private $variable;
private function doSomething() {
  // ...
}

// Protected
protected $variable;
protected function doSomething() {
  // ...
}

68 votes

Je pense que cette question bénéficierait également de réponses avec des exemples pratiques de l'utilisation de chacun, au lieu de fournir la définition littérale de ce que fait chaque mot-clé.

76 votes

Je pense vraiment que cette question devrait être publique, et non protégée.

1353voto

Sarfraz Points 168484

Vous utilisez :

  • public pour rendre cette propriété/méthode disponible de partout, d'autres classes et instances de l'objet.

  • private lorsque vous souhaitez que votre propriété/méthode ne soit visible que dans sa propre classe.

  • protected lorsque vous voulez rendre votre propriété/méthode visible dans toutes les classes qui étendent la classe actuelle, y compris la classe parent.

Si vous n'utilisez pas de modificateur de visibilité, la propriété ou la méthode sera publique.

Plus : (Pour une information complète)

84 votes

protected lorsque vous souhaitez que votre variable/fonction soit visible dans toutes les classes qui étendent la classe courante ET son classes de parents .

4 votes

@Shahid - Je ne comprends pas votre point de vue. Toute classe qui étend la classe A étend également la classe parente de A, non ?

4 votes

@JDelage - Veuillez consulter le lien. http://www.php.net/manual/en/language.oop5.visibility.php#10‌​9324

1242voto

Shankar Damodaran Points 39934

dd

Public :

Lorsque vous déclarez une méthode (fonction) ou une propriété (variable) en tant que public ces méthodes et ces propriétés sont accessibles par :

  • La même classe qui l'a déclaré.
  • Les classes qui héritent de la classe déclarée ci-dessus.
  • Tout élément étranger à cette classe peut également accéder à ces éléments.

Exemple :

<?php

class GrandPa
{
    public $name='Mark Henry';  // A public variable
}

class Daddy extends GrandPa // Inherited class
{
    function displayGrandPaName()
    {
        return $this->name; // The public variable will be available to the inherited class
    }

}

// Inherited class Daddy wants to know Grandpas Name
$daddy = new Daddy;
echo $daddy->displayGrandPaName(); // Prints 'Mark Henry'

// Public variables can also be accessed outside of the class!
$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // Prints 'Mark Henry'

Protégé :

Lorsque vous déclarez une méthode (fonction) ou une propriété (variable) en tant que protected ces méthodes et propriétés sont accessibles par

  • La même classe qui l'a déclaré.
  • Les classes qui héritent de la classe déclarée ci-dessus.

Les membres extérieurs ne peuvent pas accéder à ces variables. " Outsiders " dans le sens où ils ne sont pas des instances d'objets de la classe déclarée elle-même.

Exemple :

<?php

class GrandPa
{
    protected $name = 'Mark Henry';
}

class Daddy extends GrandPa
{
    function displayGrandPaName()
    {
        return $this->name;
    }

}

$daddy = new Daddy;
echo $daddy->displayGrandPaName(); // Prints 'Mark Henry'

$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error

L'erreur exacte sera la suivante :

PHP Erreur fatale : Impossible d'accéder à la propriété protégée GrandPa::$name


Privé :

Lorsque vous déclarez une méthode (fonction) ou une propriété (variable) en tant que private ces méthodes et ces propriétés sont accessibles par :

  • La même classe qui l'a déclaré.

Les membres outsiders ne peuvent pas accéder à ces variables. Outsiders dans le sens où ils ne sont pas des instances d'objets de la classe déclarée elle-même et même les classes qui héritent de la classe déclarée.

Exemple :

<?php

class GrandPa
{
    private $name = 'Mark Henry';
}

class Daddy extends GrandPa
{
    function displayGrandPaName()
    {
        return $this->name;
    }

}

$daddy = new Daddy;
echo $daddy->displayGrandPaName(); // Results in a Notice 

$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error

Les messages d'erreur exacts seront :

Avis : Propriété indéfinie : Papa::$name
Erreur fatale : Impossible d'accéder à la propriété privée GrandPa::$name


Disséquer la classe des grands-pères en utilisant Réflexion

Ce sujet n'est pas vraiment hors de portée, et je l'ajoute ici juste pour prouver que la réflexion est vraiment puissante. Comme je l'ai dit dans les trois exemples ci-dessus, protected y private Les membres (propriétés et méthodes) ne sont pas accessibles en dehors de la classe.

Cependant, avec la réflexion, vous pouvez faire le extra-ordinaire en accédant même protected y private membres en dehors de la classe !

Eh bien, qu'est-ce que la réflexion ?

Reflection ajoute la possibilité de faire de l'ingénierie inverse sur les classes, les interfaces, fonctions, méthodes et extensions. En outre, il offre des moyens de récupérer les commentaires de la documentation pour les fonctions, les classes et les méthodes.

Préambule

Nous avons une classe nommée Grandpas et disons que nous avons trois propriétés. Pour faciliter la compréhension, considérons qu'il y a trois grands-pères avec des noms :

  • Mark Henry
  • John Clash
  • Will Jones

Faisons-les (attribuez des modificateurs) public , protected y private respectivement. Vous savez très bien que protected y private ne sont pas accessibles en dehors de la classe. Maintenant, contredisons cette affirmation en utilisant la réflexion.

Le code

<?php

class GrandPas   // The Grandfather's class
{
    public     $name1 = 'Mark Henry';  // This grandpa is mapped to a public modifier
    protected  $name2 = 'John Clash';  // This grandpa is mapped to a protected  modifier
    private    $name3 = 'Will Jones';  // This grandpa is mapped to a private modifier
}

# Scenario 1: without reflection
$granpaWithoutReflection = new GrandPas;

# Normal looping to print all the members of this class
echo "#Scenario 1: Without reflection<br>";
echo "Printing members the usual way.. (without reflection)<br>";
foreach($granpaWithoutReflection as $k=>$v)
{
    echo "The name of grandpa is $v and he resides in the variable $k<br>";
}

echo "<br>";

#Scenario 2: Using reflection

$granpa = new ReflectionClass('GrandPas'); // Pass the Grandpas class as the input for the Reflection class
$granpaNames=$granpa->getDefaultProperties(); // Gets all the properties of the Grandpas class (Even though it is a protected or private)

echo "#Scenario 2: With reflection<br>";
echo "Printing members the 'reflect' way..<br>";

foreach($granpaNames as $k=>$v)
{
    echo "The name of grandpa is $v and he resides in the variable $k<br>";
}

Sortie :

#Scenario 1: Without reflection
Printing members the usual way.. (Without reflection)
The name of grandpa is Mark Henry and he resides in the variable name1

#Scenario 2: With reflection
Printing members the 'reflect' way..
The name of grandpa is Mark Henry and he resides in the variable name1
The name of grandpa is John Clash and he resides in the variable name2
The name of grandpa is Will Jones and he resides in the variable name3

Les idées fausses les plus courantes :

Ne confondez pas avec l'exemple ci-dessous. Comme vous pouvez toujours le voir, le private y protected les membres ne sont pas accessibles à l'extérieur de de la classe sans utiliser la réflexion

<?php

class GrandPas   // The Grandfather's class
{
    public     $name1 = 'Mark Henry';  // This grandpa is mapped to a public modifier
    protected  $name2 = 'John Clash';  // This grandpa is mapped to a protected modifier
    private    $name3 = 'Will Jones';  // This grandpa is mapped to a private modifier
}

$granpaWithoutReflections = new GrandPas;
print_r($granpaWithoutReflections);

Sortie :

GrandPas Object
(
    [name1] => Mark Henry
    [name2:protected] => John Clash
    [name3:GrandPas:private] => Will Jones
)

Fonctions de débogage

print_r , var_export y var_dump sont fonctions du débogueur . Elles présentent des informations sur une variable sous une forme lisible par l'homme. Ces trois fonctions révèlent le protected y private des objets avec PHP 5. Les membres statiques de la classe seront no être montré.


Plus de ressources :


0 votes

Je m'excuse pour cet ajout tardif à cette conversation. Pouvez-vous me dire pourquoi quelqu'un utiliserait ça ? Vous avez parfaitement expliqué comment ils fonctionnent, etc. Je voudrais simplement connaître les avantages de l'utilisation de chacun d'entre eux. Je vous remercie.

0 votes

@JamesG c'est un peu expliqué dans l'autre commentaire ci-dessus. stackoverflow.com/questions/4361553/

0 votes

Je ne sais pas pourquoi, c'est peut-être un peu hors sujet, mais personne n'a mentionné qu'en PHP, il existe deux autres modificateurs d'accès : abstract et final. Ce mot-clé ne peut être utilisé que pour les classes PHP, mais il s'agit toujours de modificateurs d'accès.

87voto

The Awnry Bear Points 1539

Il est généralement considéré comme une bonne pratique de choisir par défaut la visibilité la plus faible possible, car cela favorise l'encapsulation des données et une bonne conception des interfaces. Lorsque vous envisagez la visibilité des variables et des méthodes membres, pensez au rôle que joue le membre dans l'interaction avec d'autres objets.

Si vous "codez en fonction d'une interface plutôt que d'une implémentation", il est généralement assez simple de prendre des décisions en matière de visibilité. En général, les variables doivent être privées ou protégées, sauf si vous avez une bonne raison de les exposer. Utilisez plutôt des accesseurs publics (getters/setters) pour limiter et réguler l'accès aux éléments internes d'une classe.

Pour utiliser une voiture comme analogie, des choses comme la vitesse, le rapport de vitesse et la direction seraient des variables d'instance privées. Vous ne souhaitez pas que le conducteur puisse manipuler directement des éléments tels que le rapport air/carburant. Au lieu de cela, vous exposez un nombre limité d'actions en tant que méthodes publiques. L'interface d'une voiture pourrait inclure des méthodes telles que accelerate() , deccelerate() / brake() , setGear() , turnLeft() , turnRight() etc.

Le conducteur ne sait pas et ne doit pas se soucier de la manière dont ces actions sont mises en œuvre par les composants internes de la voiture, et exposer cette fonctionnalité pourrait être dangereux pour le conducteur et les autres usagers de la route. D'où la bonne pratique consistant à concevoir une interface publique et à encapsuler les données derrière cette interface.

Cette approche vous permet également de modifier et d'améliorer l'implémentation des méthodes publiques dans votre classe sans rompre le contrat de l'interface avec le code client. Par exemple, vous pouvez améliorer la méthode accelerate() pour être plus économe en carburant, mais l'utilisation de cette méthode resterait la même ; le code client n'aurait pas besoin d'être modifié mais bénéficierait quand même de l'amélioration de votre efficacité.

Edit : Puisqu'il semble que vous soyez toujours en train d'apprendre les concepts de l'orientation objet (qui sont beaucoup plus difficiles à maîtriser que la syntaxe de n'importe quel langage), je hautement Je vous recommande de vous procurer un exemplaire de Objets, modèles et pratique de PHP par Matt Zandstra. C'est le livre qui m'a appris en premier comment d'utiliser la POO efficacement, plutôt que de m'enseigner la syntaxe. J'avais appris la syntaxe des années auparavant, mais c'était inutile si je ne comprenais pas le "pourquoi" de la POO.

3 votes

Le livre recommandé dans l'édition de ce post est vraiment très excellent. Le morceau I jusqu'à présent s'est avéré très instructif. Les premiers chapitres ont répondu à la plupart de mes questions relatives à la classe.

0 votes

Les livres qui m'ont permis de vraiment comprendre les objets, sans encombrer ma réflexion de détails inutiles, comme les exemples de Smalltalk, sont ceux de David A. Taylor, à savoir Technologie orientée objet : Guide du gestionnaire y Ingénierie d'entreprise avec la technologie des objets . Tous deux ne font que 100 pages, et sont assez faciles à lire en un après-midi. Bien sûr, il y a aussi le livre de Gamma et al. Modèles de conception Cependant, l'approche de base peut être décrite simplement par "sous-classez ce que vous voulez faire varier".

0 votes

Une très belle analogie. Vous en avez une pour le protégé et le privé ?

85voto

Olaf Points 4376

private - ne sont accessibles qu'à partir de l'INTERIEUR de la classe

protected - sont accessibles à partir de l'intérieur de la classe et de l'intérieur des classes.

public - peuvent être accédés à partir de code EXTERIEUR à la classe ainsi que

Cela s'applique aussi bien aux fonctions qu'aux variables.

0 votes

Je ne suis pas sûr que la définition de "protégé" soit correcte ici. D'après la réponse sélectionnée, il semble que "protégé" soit accessible uniquement à partir de la classe héritée et non à partir de la classe originale/parente. Dire "DANS la classe" peut être un peu confus.

7 votes

Je ne pense pas, en fait, il semble que la réponse choisie soit celle qui prête à confusion ici. Voir le commentaire de Shahid. IMHO une méthode protégée peut très bien être accessible depuis la classe originale.

0 votes

Une classe peut-elle accéder au public d'une autre classe ?

28voto

Matthew Watts Points 141

La différence est la suivante :

Public : : Une variable ou une méthode publique peut être accédée directement par tout utilisateur de la classe.

Protected : : Une variable ou une méthode protégée ne peut pas être accédée par les utilisateurs de la classe mais peut être accédée à l'intérieur d'une sous-classe qui hérite de la classe.

Private : : Une variable ou une méthode privée n'est accessible qu'à l'intérieur de la classe dans laquelle elle est définie, ce qui signifie qu'elle ne peut pas être appelée par un enfant qui étend la classe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X