Zugriffsmodifikatoren im Detail
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy. Lektion 39 von 91.
Nachdem du nun die drei Zugriffsmodifikatoren verstanden hast, wollen wir untersuchen, wie sie sich in Vererbungsszenarien verhalten. Die wichtigste Erkenntnis ist, dass protected-Member für Unterklassen zugänglich werden, während private-Member selbst vor Unterklassen 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 method!
}
}
$car = new Car("Toyota", "V6", "ABC123");
echo $car->getDetails();
Ausgabe:
Toyota - V6Die Klasse Car kann auf $brand (öffentlich) zugreifen und getEngineInfo() (geschützt) aufrufen, hat aber keinen Zugriff auf $serialNumber oder getSerial(), da diese für Vehicle privat sind. Diese Unterscheidung ermöglicht es dir, einige interne Details mit untergeordneten Klassen zu teilen, während andere vollständig verborgen bleiben.
Wichtiger Punkt: Verwende protected, wenn abgeleitete Klassen Zugriff auf interne Daten oder Methoden benötigen, und private, wenn selbst abgeleitete Klassen bestimmte Implementierungsdetails nicht berühren sollten.
Aufgabe
EinfachErstellen wir ein Geräteverwaltungssystem, das untersucht, wie sich Zugriffsmodifikatoren bei Vererbung verhalten. Du erstellst eine Basisklasse Device mit Eigenschaften auf unterschiedlichen Sichtbarkeitsebenen und erweiterst sie anschließend mit einer Klasse Smartphone, die veranschaulicht, auf welche Member Unterklassen zugreifen können und auf welche nicht.
Du organisierst deinen Code über drei Dateien:
Device.php: Erstelle eine KlasseDevice, die elektronische Geräte mit unterschiedlichen Stufen der Datenvertraulichkeit repräsentiert. Füge Folgendes hinzu:- Eine
public-Eigenschaft$brandfür den Namen des Herstellers - Eine
protected-Eigenschaft$modelNumberzur internen Identifizierung - Eine
private-Eigenschaft$manufacturingCodefür ausschließlich werkseitig verwendete Daten
private-MethodegetManufacturingCode()hinzu, die den Fertigungscode zurückgibt. Füge einepublic-MethodegetModelInfo()hinzu, die"Model: [modelNumber]"zurückgibt. Füge schließlich einepublic-MethodegetFullCode()hinzu, die"[brand]-[manufacturingCode]"zurückgibt. Dies veranschaulicht, wie die Klasse selbst auf ihre eigenen privaten Member zugreifen kann.- Eine
Smartphone.php: Erstelle eine KlasseSmartphone, dieDeviceerweitert. Binde die Device-Datei ein. Der Konstruktor soll brand, modelNumber, manufacturingCode und den Namen eines Betriebssystems akzeptieren. Rufe den Konstruktor der übergeordneten Klasse mit den ersten drei Werten auf und speichere anschließend das Betriebssystem in einer privaten Eigenschaft. Füge eine öffentliche MethodegetDeviceDetails()hinzu, die"[brand] [modelNumber] running [os]"zurückgibt. Beachte, dass du direkt auf die öffentliche Eigenschaft$brandund die geschützte Eigenschaft$modelNumberzugreifen kannst, aber nicht direkt auf die private Eigenschaft$manufacturingCode: Stattdessen müsstest du die geerbte öffentliche MethodegetFullCode()verwenden.main.php: Binde die Smartphone-Datei ein. Du erhältst vier Eingaben: einen Markennamen, eine Modellnummer, einen Fertigungscode und ein Betriebssystem. Erstelle mit diesen Werten eine Instanz vonSmartphone. Gib 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 Aufgabe hebt den entscheidenden Unterschied hervor: Deine Klasse Smartphone kann die von Device geerbte geschützte Eigenschaft $modelNumber uneingeschränkt 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 zur Verfügung stellt.
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: Erstelle eine Smartphone-Instanz mit den Eingabewerten
// TODO: Gib das Ergebnis von getDeviceDetails() aus
// TODO: Gib das Ergebnis der geerbten getModelInfo()-Methode aus
// TODO: Gib das Ergebnis der geerbten getFullCode()-Methode 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 OOPKlassen vs. ObjekteDas Schlüsselwort $thisMethodenEigenschaftenKonstruktor (__construct)Destruktor (__destruct)Rückblick – Einfacher Taschenrechner4Vererbung
Grundlegende VererbungDas Schlüsselwort parent::MethodenüberschreibungDas Schlüsselwort finalAbstrakte KlassenRückblick – Mitarbeiterhierarchie7Kapselung
Öffentlich, geschützt, privatZugriffsmodifikatoren im DetailGetter und SetterInformationsverbergungKonstruktor-Promotion (8.0)Wiederholung – System zur Verwaltung von Schülerdatensätzen2Namespaces & Autoloading
Einführung in NamespacesDas use-SchlüsselwortPSR-4-Autoloading-StandardComposer-AutoloaderRückblick – Organisiertes Projekt5Schnittstellen & Verträge
Einführung in SchnittstellenSchnittstellen implementierenMehrere Schnittstellen implementierenSchnittstelle vs. abstrakte KlasseTyp-Hinweise mit SchnittstellenRückblick – Formrechner8Magische Methoden
Einführung in magische Methoden__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Objektklonen__serialize & __unserializeRückblick – Benutzerdefinierte Sammlung11Typsystem & Fehlerbehandlung
TypdeklarationenNullable-TypenUnion- & Intersection-TypenException-KlassenBenutzerdefinierte Exception-HierarchieTry, Catch, FinallyRückblick – Formularvalidator14Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Klassen-Eigenschaften
Instanz- vs. statische EigenschaftenKonstanten in KlassenStatische Methoden & EigenschaftenPrivate & geschützte EigenschaftenSchreibgeschützte Eigenschaften (PHP 8.1)Zusammenfassung – Bankkonto-Manager6Polymorphie
Methodenüberschreibung erneut betrachtetPolymorphie über SchnittstellenTyp-Hinweise & Union-TypenSpätes statisches BindenRückblick – Zahlungsabwickler9Traits
Einführung in TraitsMehrere Traits verwendenAuflösung von Trait-KonfliktenAbstrakte Methoden in TraitsTraits vs. Vererbung12Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster15Abschließende Herausforderungen
E-Learning-PlattformBankingsystemEntwicklung einer SpielfigurFahrzeugvermietungÜbe selbstständig: Online-PHP-Compiler