Sichtbarkeit in OOP
In der objektorientierten Programmierung (OOP) könnt ihr Eigenschaften (Klassenvariable) und Methoden (Klassenfunktion) unterschiedliche Sichtbarkeiten zuweisen. Dabei wird zwischen den Sichtbarkeiten public, protected, und private unterschieden.
Durch unterschiedliche Sichtbarkeiten könnt ihr kontrollieren, wer zugriff auf eine Eigenschaft oder eine Methode hat. So könnt ihr z.B. bestimmen, dass eine Eigenschaft nur innerhalb einer Klasse sichtbar ist, von außen aber nicht darauf zugriffen werden kann. Die drei Begriffe bedeuten dabei:
- public: Public bedeutet Vollzugriff, jeder kann auf diese Variable oder Methode zugreifen.
- protected: Auf die Variable oder Methode kann nur innerhalb der Klasse und in vererbten Klassen zugegriffen werden.
- private: Der restriktivste Typ. Nur innerhalb der Klasse kann auf solche Variablen und Methoden zugegriffen werden.
In PHP 4 war noch der Begriff var definiert. Dies entspricht in PHP 5 und neuer der Sichtbarkeit public.
Beispiel
Nachfolgend ein Beispiel um euch die Sichtbarkeit bei der objektorientierten Programmierung näher zu bringen:
<?php class User { public $name; protected $email; private $password; public function setEmail($newEmail) { if($this->isValidEmail($newEmail)) { $this->email = $newEmail; } } public function getEmail() { return $this->email; } public function setRandomPassword() { $randomPassword = strval(rand(1,10)); //Dies ist nicht sonderlich sicher $this->password = $this->hashPassword($randomPassword); return $randomPassword; } public function isCorrectPassword($password) { return $this->hashPassword($password) == $this->password; } protected function isValidEmail($email) { return filter_var($email, FILTER_VALIDATE_EMAIL) !== false; } private function hashPassword($password) { return sha1($password); } } $max = new User(); $max->name = "Max Mustermann"; $max->setEmail("[email protected]"); echo "Die E-Mail-Adresse ist: ".$max->getEmail()."<br />"; $randomPW = $max->setRandomPassword(); echo "Zufälliges Passwort: $randomPW <br />"; echo "Ist das Passwort 5 korrekt: "; var_dump($max->isCorrectPassword("5")); ?>
Im obigen Beispiel haben wir drei Eigenschaften: $name, $email und $password. Die Eigenschaften $name könnt ihr dabei problemlos auch außerhalb der Klasse abrufen oder verändern, wie in Zeile 37 gezeigt. Da $email und $password aber die Sichtbarkeit protected bzw. private besitzen, könnt ihr diese nicht außerhalb eures Codes abrufen. Führt ihr z.B. den Code echo $max->email; aus, so erhaltet ihr eine Fatal error-Fehlermeldung. Die beiden Eigenschaften $email und $password sind für Code außerhalb der Klasse nicht sichtbar.
Auf diese beiden Eigenschaften aber innerhalb der Klasse zuzugreifen ist kein Problem, wie in den Zeilen 7 bis 21 dargestellt. Mit den beiden public Methoden setEmail() und getEmail() ermöglicht ihr es aber Code von außerhalb die E-Mail-Adresse zu setzen bzw. auch wieder abzrufen um sie z.B. auszugeben. Durch die Überprüfung in setEmail() wird beispielsweise sichergestellt, dass die Eigenschaft $email stets nur eine gültige E-Mail-Adresse beinhaltet und keinen Müll.
Im obigen Beispiel haben wir auch unterschiedliche Sichtbarkeiten für die verschiedenen Methoden. So könnt ihr z.B. nicht die Methode $max->isValidEmail("test"); ausführen, da diese Methode die Sichtbarkeit protected besitzt. Damit ist diese Methode nur innerhalb der Klasse und in entsprechenden vererbten Klassen sichtbar.
Warum sollte ich Sichtbarkeiten wählen und wann welche?
Bei dem obigen Code sowie bei kleinen Projekten scheint das Spezifizieren der Sichtbarkeit unsinnig. Bei größeren Projekten, an denen ggf. mehrere Personen mitentwickeln, könnt ihr dadurch gut eure interne Funktionsweise der Klasse von der Außenwelt verstecken.
Angenommen im obigen Code wollt ihr nicht nur überprüfen, ob die E-Mail gültig ist, sondern auch dass sie nicht auf einer Blacklist mit verbannten E-Mail-Adressen steht. Solch eine Änderung wäre im obigen Code recht einfach, ihr müsstet nur den Code in der Methode setEmail() anpassen. Und schon könntet ihr sicher sein, dass an keiner anderen Stelle mehr diese Überprüfung fehlt, da überall auf diese Methode zugriffen werden muss. Hättet ihr stattdessen die Eigenschaft $email als public definiert, so könntet es sein, dass ihr oder ein Mitentwickler an irgendeiner Stelle direkt auf die Eigenschaft $email zugreift und dort nicht überprüft, dass diese E-Mail-Adresse verbannt wurde. Dementsprechend müsste ihr bei einer so kleinen Veränderung euren gesamten Code durchsuchen um zu überprüfen dass bei jeder Zuweisung der E-Mail-Adresse auch alle Überprüfungen durchgeführt werden.
Prinzipiell solltet ihr public verwenden, wenn ihr möchtet dass diese Eigenschaft oder Methode auch außerhalb eurer Klasse genutzt werden soll. Verwendet stattdessen protected oder private für alle internen Eigenschaften und Methoden, wo ihr nicht möchtet, dass außerhalb dieser Klasse auf diese zugriffen wird.
Autor: Nils Reimers