Menu
Coddy logo textTech

Modificateurs d'accès en détail

Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy — leçon 39 sur 91.

Maintenant que vous comprenez les trois modificateurs d'accès, explorons comment ils se comportent dans les scénarios d'héritage. L'idée clé est que les membres protected deviennent accessibles aux classes enfants, tandis que les membres private restent cachés même pour les enfants.

<?php
class Vehicle {
    public $brand;
    protected $engineType;
    private $serialNumber;
    
    public function __construct($brand, $engine, $serial) {
        $this->brand = $brand;
        $this->engineType = $engine;
        $this->serialNumber = $serial;
    }
    
    private function getSerial() {
        return $this->serialNumber;
    }
    
    protected function getEngineInfo() {
        return $this->engineType;
    }
}

class Car extends Vehicle {
    public function getDetails() {
        return $this->brand . " - " . $this->getEngineInfo();
        // $this->serialNumber provoquerait une erreur - privé !
        // $this->getSerial() échouerait également - méthode privée !
    }
}

$car = new Car("Toyota", "V6", "ABC123");
echo $car->getDetails();

Sortie :

Toyota - V6

La classe Car peut accéder à $brand (public) et appeler getEngineInfo() (protégée), mais n'a pas accès à $serialNumber ou getSerial() car ils sont privés pour Vehicle. Cette distinction vous permet de partager certains détails internes avec les classes enfants tout en gardant les autres complètement cachés.

Point clé : Utilisez protected lorsque les classes enfants ont besoin d'accéder à des données ou des méthodes internes, et private lorsque même les classes enfants ne devraient pas toucher à certains détails d'implémentation.

challenge icon

Défi

Facile

Construisons un système de gestion d'appareils qui explore le comportement des modificateurs d'accès à travers l'héritage. Vous allez créer une classe de base Device avec des propriétés à différents niveaux de visibilité, puis l'étendre avec une classe Smartphone qui démontre quels membres les classes enfants peuvent ou ne peuvent pas accéder.

Vous organiserez votre code sur trois fichiers :

  • Device.php — Créez une classe Device qui représente des appareils électroniques avec différents niveaux de sensibilité des données. Incluez :
    • Une propriété public $brand pour le nom du fabricant
    • Une propriété protected $modelNumber pour l'identification interne
    • Une propriété private $manufacturingCode pour les données réservées à l'usine
    Le constructeur doit accepter les trois valeurs. Ajoutez une méthode private getManufacturingCode() qui retourne le code de fabrication. Ajoutez une méthode public getModelInfo() qui retourne "Model: [modelNumber]". Enfin, ajoutez une méthode public getFullCode() qui retourne "[brand]-[manufacturingCode]" — cela démontre comment la classe elle-même peut accéder à ses propres membres privés.
  • Smartphone.php — Créez une classe Smartphone qui étend Device. Incluez le fichier Device. Le constructeur doit accepter la marque, le numéro de modèle, le code de fabrication et un nom de système d'exploitation. Appelez le constructeur parent avec les trois premières valeurs, puis stockez l'OS dans une propriété privée. Ajoutez une méthode publique getDeviceDetails() qui retourne "[brand] [modelNumber] running [os]". Remarquez comment vous pouvez accéder directement au $brand public et au $modelNumber protégé, mais vous ne pouvez pas accéder directement au $manufacturingCode privé — vous devrez utiliser la méthode publique héritée getFullCode() à la place.
  • main.php — Incluez le fichier Smartphone. Vous recevrez quatre entrées : un nom de marque, un numéro de modèle, un code de fabrication et un système d'exploitation. Créez une instance de Smartphone avec ces valeurs. Affichez trois lignes :
    • Le résultat de l'appel à getDeviceDetails()
    • Le résultat de l'appel à la méthode héritée getModelInfo()
    • Le résultat de l'appel à la méthode héritée getFullCode()

Ce défi met en évidence la distinction clé : votre classe Smartphone peut utiliser librement le $modelNumber protégé hérité de Device, mais le $manufacturingCode privé et getManufacturingCode() restent complètement cachés — accessibles uniquement via l'interface publique que Device choisit d'exposer.

Aide-mémoire

Dans l'héritage, les membres protected sont accessibles aux classes enfants, tandis que les membres private restent cachés même pour les enfants.

<?php
class Vehicle {
    public $brand;
    protected $engineType;
    private $serialNumber;
    
    public function __construct($brand, $engine, $serial) {
        $this->brand = $brand;
        $this->engineType = $engine;
        $this->serialNumber = $serial;
    }
    
    private function getSerial() {
        return $this->serialNumber;
    }
    
    protected function getEngineInfo() {
        return $this->engineType;
    }
}

class Car extends Vehicle {
    public function getDetails() {
        return $this->brand . " - " . $this->getEngineInfo();
        // $this->serialNumber provoquerait une erreur - private !
        // $this->getSerial() échouerait également - méthode privée !
    }
}

$car = new Car("Toyota", "V6", "ABC123");
echo $car->getDetails(); // Toyota - V6

Les classes enfants peuvent accéder à :

  • aux propriétés et méthodes public
  • aux propriétés et méthodes protected

Les classes enfants ne peuvent pas accéder à :

  • aux propriétés et méthodes private (celles-ci restent exclusives à la classe parente)

Bonne pratique : Utilisez protected lorsque les classes enfants ont besoin d'accéder à des données ou des méthodes internes, et private lorsque même les classes enfants ne devraient pas toucher à certains détails d'implémentation.

Essayez vous-même

<?php
require_once 'Smartphone.php';

// Lire les entrées
$brand = trim(fgets(STDIN));
$modelNumber = trim(fgets(STDIN));
$manufacturingCode = trim(fgets(STDIN));
$os = trim(fgets(STDIN));

// TODO: Créer une instance de Smartphone avec les valeurs d'entrée

// TODO: Afficher le résultat de getDeviceDetails()

// TODO: Afficher le résultat de la méthode héritée getModelInfo()

// TODO: Afficher le résultat de la méthode héritée getFullCode()
?>
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet