Zugriff auf Kind-Eigenschaften in geerbter Methode
shn
- php
Servus,
ich steh gerade etwas auf dem Schlauch ;) Folgendes Szenario:
class A {
protected $foo;
public function __get($property) {
return ( isset($this->$property) ) ? true : false
}
}
class B {
protected $bar;
}
$b = new B;
$b->foo; // true
$b->bar; // false
Entgegen meinen Erwartungen existiert $bar beim Aufruf von __get() nicht, da ich anscheinend aus einer geerbten, nicht überschriebenen Methode der Elternklasse nicht auf Eigenschaften der Kindklasse zugreifen kann.
Gibt es eine Möglichkeit dies dennoch zu realisieren, ohne __get() in jeder Kindklasse neu definieren zu müssen?
Gruss
Patrick
echo $begrüßung;
ich steh gerade etwas auf dem Schlauch ;) Folgendes Szenario:
class A {
protected $foo;public function __get($property) {
return ( isset($this->$property) ) ? true : false
}
}class B {
protected $bar;
}$b = new B;
$b->foo; // true
$b->bar; // false
Das ist nicht direkt der von dir verwendete Code. Es fehlen Teile, nämlich ein "extends A" (und eine Zuweisung, aber dazu komme ich später). Außerdem hast du nicht getestet, ob sich das Beispiel genauso verhält, denn in beiden Fällen kommt false raus. Das liegt daran, dass die Eigeschaften zwar existieren, aber ihnen kein Wert zugewiesen ist. Sie haben dann den Default-Wert null und der ergibt beim isset() ebenfalls false.
Wenn du nun
protected $foo = 42;
und
protected $bar = 23;
notierst, oder die beiden Eigenschaften anderweitig sinnvoll (außer eben null) initialisierst, erhältst du beides Mal true.
Außerdem liefert isset() bereits true oder false als Ergebnis. Die Verwendung des ternären Operators plus true und false ist überflüssig.
echo "$verabschiedung $name";
Servus,
ups, da ist beim reduzieren wohl so einiges verloren gegangen - hätte den Test wohl doch besser mal parsen lassen ... dann wär mir auch gleich aufgefallen, wo das Problem lag - ich sag ja ich war total durch den Wind ;)
Also mein Ausgangscode war (trotz der zahlreichen Fehler im Beispiel) soweit korrekt. Das Problem war, dass fragliche Properties in B nicht protected sondern private waren.
Kannst du mir erklären, warum das ganze nicht klappt, wenn $bar private ist? Ich hatte Vererbung bisher immer so verstanden, dass geerbte Methoden im Scope der Kindklasse, und nicht in dem der Elternklasse, aufgerufen werden - worans hier offensichtlich scheitert.
Gruss
Patrick
echo $begrüßung;
Das Problem war, dass fragliche Properties in B nicht protected sondern private waren.
Kannst du mir erklären, warum das ganze nicht klappt, wenn $bar private ist? Ich hatte Vererbung bisher immer so verstanden, dass geerbte Methoden im Scope der Kindklasse, und nicht in dem der Elternklasse, aufgerufen werden - worans hier offensichtlich scheitert.
Nein, ich kann es nicht fundiert erklären, aber ich versuche es. PHPs OOP ist ein Aufsatz auf eine prozedurale Sprache. Manche Dinge funktionieren da anders als bei von vorn herein objektorientiert gestalteten Systemen. Wenn ich das richtig in Erinnerung habe, wird eine Methode quasi-statisch aufgerufen, also Class::method() und $this zeigt dabei auf die aktuelle Instanz. In deinem Fall kommt noch etwas Magie zum Einsatz, der Zugriff auf $b->bar resultiert in einem Aufruf von A::__get() mit einem auf $b zeigenden $this. $b->bar ist private, deswegen können nur Methoden von B darauf zugreifen. Was spricht in deinem Fall dagegen, $b->bar protected zu deklarieren? Bedenke dabei auch, dass die Zugriffsmodifizierer nicht für sicherheitsrelevante Zwecke gedacht sind, sondern vielmehr nur einen Hinweis zur vom ursprünglichen Autor vorgesehenen Verwendung darstellen.
echo "$verabschiedung $name";
Hallo,
Kannst du mir erklären, warum das ganze nicht klappt, wenn $bar
private ist? Ich hatte Vererbung bisher immer so verstanden, dass
geerbte Methoden im Scope der Kindklasse, und nicht in dem der
Elternklasse, aufgerufen werden - worans hier offensichtlich
scheitert.
In OOP stehen private Methoden und Variablen _ausschliesslich_ der
Klasse zu Verfuegung, in der sie deklariert sind.
Und die implementierenden Klassen koennen _nicht_ auf diese Werte /
Methoden zugreifen. (*)
Gruss
MichaReg
(*) Das stimmt nicht so ganz - private Felder/Methoden/Properties
koennen durchaus von x-beliebigen Klassen, die eine Instanz der zu
aendernden Klasse besitzen, aufgerufen bzw. veraendert werden. Denn es
gibt die Ausnahme der Reflection. Wie das allerdings unter PHP
realisiert ist bzw. ob das ueberhaupt unter PHP existiert, kann ich
dir nicht sagen.
Servus,
In OOP stehen private Methoden und Variablen _ausschliesslich_ der
Klasse zu Verfuegung, in der sie deklariert sind.
Und die implementierenden Klassen koennen _nicht_ auf diese Werte /
Methoden zugreifen. (*)
Was du beschreibst ist aber die 'andere Richtung' - bei mir hingegen befindet sich die private Property in der Kindklasse, welche die implementierte Methode ausführt.
Mein Verständnis war, dass bei Vererbung die implementierten Eigenschaften und Methoden teil der Kindklasse werden, sich also quasi so verhalten, als wären sie direkt dort deklariert. Scheinbar ist dem nicht so.
Nach dedlfix' Ausführungen hört es sich nach einer Eigenart von PHP an. Ist das in anderen Sprachen genauso?
Gruss
Patrick
Hallo Patrick,
Was du beschreibst ist aber die 'andere Richtung'
Ich hatte vesucht es so allgemein wie moeglich zu halten.
Was ich sagen wollte:
Private Variablen o. Methoden sind immer nur und ausschliesslich
in der Klasse zugreifbar, in der sie auch deklariert wurden.
Nach dedlfix' Ausführungen hört es sich nach einer Eigenart von PHP
an. Ist das in anderen Sprachen genauso?
Also mir ist bisher keine Sprache untergekommen, die das anders
handhabt. Gerade in Bezug auf kompilierende Sprachen (wie zB Java, C#,
C++ o.ae.) wird bereits der Compiler meckern, da er die Variable gar
nicht kennen kann (da sie ja nicht im Scope der Klasse liegt).
Gruss,
MichaReg
Hallo,
mich wundert warum isset() ueberhaupt einmal true liefert..
Oder hast du nur einen Ausschnitt gepostet?
Grus
MR