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 - V6Die 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.
Aufgabe
EinfachLassen 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 KlasseDevice, die elektronische Geräte mit unterschiedlichen Stufen der Datensensibilität repräsentiert. Fügen Sie hinzu:- Eine
publicEigenschaft$brandfür den Namen des Herstellers - Eine
protectedEigenschaft$modelNumberfür die interne Identifikation - Eine
privateEigenschaft$manufacturingCodefür werksinterne Daten
privateMethodegetManufacturingCode()hinzu, die den Fertigungscode zurückgibt. Fügen Sie einepublicMethodegetModelInfo()hinzu, die"Model: [modelNumber]"zurückgibt. Fügen Sie schließlich einepublicMethodegetFullCode()hinzu, die"[brand]-[manufacturingCode]"zurückgibt — dies zeigt, wie die Klasse selbst auf ihre eigenen privaten Mitglieder zugreifen kann.- Eine
Smartphone.php— Erstellen Sie eine KlasseSmartphone, dieDeviceerweitert. 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 MethodegetDeviceDetails()hinzu, die"[brand] [modelNumber] running [os]"zurückgibt. Beachten Sie, wie Sie direkt auf das öffentliche$brandund das geschützte$modelNumberzugreifen können, aber nicht direkt auf das private$manufacturingCode— stattdessen müssten Sie die geerbte öffentliche MethodegetFullCode()verwenden.main.php— Binden Sie die Datei Smartphone ein. Sie erhalten vier Eingaben: einen Markennamen, eine Modellnummer, einen Fertigungscode und ein Betriebssystem. Erstellen Sie eineSmartphone-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()
- Das Ergebnis des Aufrufs von
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:
publicEigenschaften und MethodenprotectedEigenschaften und Methoden
Kindklassen können nicht zugreifen auf:
privateEigenschaften 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
?>Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas $this-SchlüsselwortMethodenEigenschaftenKonstruktor (__construct)Destruktor (__destruct)Rückblick - Einfacher Taschenrechner4Vererbung
Grundlagen der VererbungDas parent:: SchlüsselwortMethoden überschreibenDas final SchlüsselwortAbstrakte KlassenZusammenfassung – Mitarbeiter-Hierarchie7Kapselung
Public, Protected, PrivateZugriffsmodifikatoren im DetailGetter und SetterInformation HidingConstructor Promotion (8.0)Zusammenfassung – Studentenverwaltungssystem2Namensräume & Autoloading
Einführung in NamensräumeDas use-SchlüsselwortPSR-4 Autoloading-StandardComposer AutoloaderZusammenfassung – Organisiertes Projekt5Interfaces & Verträge
Einführung in InterfacesInterfaces implementierenMehrfache Interface-ImplementierungInterface vs. Abstrakte KlasseType Hinting mit InterfacesZusammenfassung – Formen-Rechner8Magische Methoden
Einführung in magische Methoden__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Objekt-Klonen__serialize & __unserializeZusammenfassung - Eigene Collection11Typsystem & Fehlerbehandlung
TypdeklarationenNullable-TypenUnion- & Intersection-TypenException-KlassenEigene Exception-HierarchieTry, Catch, FinallyZusammenfassung - Formular-Validator14Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Klasseneigenschaften
Instanz- vs. statische EigenschaftenKonstanten in KlassenStatische Methoden & EigenschaftenPrivate & geschützte EigenschaftenReadonly-Eigenschaften (PHP 8.1)Zusammenfassung – Bankkonto-Manager6Polymorphismus
Method Overriding erneut betrachtetPolymorphismus über InterfacesType Hinting & Union TypesLate Static BindingZusammenfassung – Payment Processor9Traits
Einführung in TraitsVerwendung mehrerer TraitsKonfliktlösung bei TraitsAbstrakte Methoden in TraitsTraits vs. Vererbung12Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster15Abschlussherausforderungen
E-Learning-PlattformBanksystemSpielcharakter-EntwicklungFahrzeugvermietung