Menu
Coddy logo textTech

Zugriffsmodifikatoren im Detail

Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy — Lektion 39 von 91.

Nachdem Sie nun die drei Zugriffsmodifikatoren verstehen, lassen Sie uns untersuchen, wie sie sich in Vererbungsszenarien verhalten. Die wichtigste Erkenntnis ist, dass protected Member für Kindklassen zugänglich werden, während private Member selbst vor Kindern verborgen bleiben.

<?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 würde einen Fehler verursachen - private!
        // $this->getSerial() würde ebenfalls fehlschlagen - private Methode!
    }
}

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

Ausgabe:

Toyota - V6

Die Klasse Car kann auf $brand (public) zugreifen und getEngineInfo() (protected) aufrufen, hat aber keinen Zugriff auf $serialNumber oder getSerial(), da diese für Vehicle privat sind. Diese Unterscheidung ermöglicht es Ihnen, einige interne Details mit Kindklassen zu teilen, während andere vollständig verborgen bleiben.

Wichtiger Punkt: Verwenden Sie protected, wenn Kindklassen Zugriff auf interne Daten oder Methoden benötigen, und private, wenn selbst Kindklassen bestimmte Implementierungsdetails nicht berühren sollten.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Geräteverwaltungssystem erstellen, das untersucht, wie sich Zugriffsmodifikatoren bei Vererbung verhalten. Sie erstellen eine Basisklasse Device mit Eigenschaften auf verschiedenen Sichtbarkeitsebenen und erweitern diese dann um eine Klasse Smartphone, die demonstriert, auf welche Mitglieder Kindklassen zugreifen können und auf welche nicht.

Sie organisieren Ihren Code in drei Dateien:

  • Device.php — Erstellen Sie eine Klasse Device, die elektronische Geräte mit unterschiedlichen Stufen der Datensensibilität repräsentiert. Fügen Sie hinzu:
    • Eine public Eigenschaft $brand für den Namen des Herstellers
    • Eine protected Eigenschaft $modelNumber für die interne Identifikation
    • Eine private Eigenschaft $manufacturingCode für werksinterne Daten
    Der Konstruktor sollte alle drei Werte akzeptieren. Fügen Sie eine private Methode getManufacturingCode() hinzu, die den Fertigungscode zurückgibt. Fügen Sie eine public Methode getModelInfo() hinzu, die "Model: [modelNumber]" zurückgibt. Fügen Sie schließlich eine public Methode getFullCode() hinzu, die "[brand]-[manufacturingCode]" zurückgibt — dies zeigt, wie die Klasse selbst auf ihre eigenen privaten Mitglieder zugreifen kann.
  • Smartphone.php — Erstellen Sie eine Klasse Smartphone, die Device erweitert. Binden Sie die Datei Device ein. Der Konstruktor sollte brand, modelNumber, manufacturingCode und den Namen eines Betriebssystems akzeptieren. Rufen Sie den Eltern-Konstruktor mit den ersten drei Werten auf und speichern Sie dann das OS in einer privaten Eigenschaft. Fügen Sie eine öffentliche Methode getDeviceDetails() hinzu, die "[brand] [modelNumber] running [os]" zurückgibt. Beachten Sie, wie Sie direkt auf das öffentliche $brand und das geschützte $modelNumber zugreifen können, aber nicht direkt auf das private $manufacturingCode — stattdessen müssten Sie die geerbte öffentliche Methode getFullCode() verwenden.
  • main.php — Binden Sie die Datei Smartphone ein. Sie erhalten vier Eingaben: einen Markennamen, eine Modellnummer, einen Fertigungscode und ein Betriebssystem. Erstellen Sie eine Smartphone-Instanz mit diesen Werten. Geben Sie drei Zeilen aus:
    • Das Ergebnis des Aufrufs von getDeviceDetails()
    • Das Ergebnis des Aufrufs der geerbten Methode getModelInfo()
    • Das Ergebnis des Aufrufs der geerbten Methode getFullCode()

Diese Herausforderung verdeutlicht den entscheidenden Unterschied: Ihre Klasse Smartphone kann die von Device geerbte geschützte Eigenschaft $modelNumber frei verwenden, aber die private Eigenschaft $manufacturingCode und die Methode getManufacturingCode() bleiben vollständig verborgen — sie sind nur über die öffentliche Schnittstelle zugänglich, die Device bereitstellt.

Spickzettel

Bei der Vererbung sind protected Member für Kindklassen zugänglich, während private Member selbst vor Kindklassen verborgen bleiben.

<?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 würde einen Fehler verursachen - private!
        // $this->getSerial() würde ebenfalls fehlschlagen - private Methode!
    }
}

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

Kindklassen können zugreifen auf:

  • public Eigenschaften und Methoden
  • protected Eigenschaften und Methoden

Kindklassen können nicht zugreifen auf:

  • private Eigenschaften und Methoden (diese bleiben exklusiv der Elternklasse vorbehalten)

Best Practice: Verwenden Sie protected, wenn Kindklassen Zugriff auf interne Daten oder Methoden benötigen, und private, wenn selbst Kindklassen bestimmte Implementierungsdetails nicht berühren sollten.

Probier es selbst

<?php
require_once 'Smartphone.php';

// Eingaben lesen
$brand = trim(fgets(STDIN));
$modelNumber = trim(fgets(STDIN));
$manufacturingCode = trim(fgets(STDIN));
$os = trim(fgets(STDIN));

// TODO: Erstellen Sie eine Smartphone-Instanz mit den Eingabewerten

// TODO: Geben Sie das Ergebnis von getDeviceDetails() aus

// TODO: Geben Sie das Ergebnis der geerbten Methode getModelInfo() aus

// TODO: Geben Sie das Ergebnis der geerbten Methode getFullCode() aus
?>
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung