2008-09-17 3 views
1

Im Folgenden finden Sie ein Beispiel für eine Klassenhierarchie und einen Code. Was ich suche, ist eine Möglichkeit zu bestimmen, ob 'ChildClass1' oder 'ChildClass2' die statische Methode whoAmI() aufgerufen hat, ohne sie in jeder Kindklasse neu zu implementieren.Gibt es eine Möglichkeit, die Zielklasse in statischen Methoden zu erkennen?

<?php 

abstract class ParentClass { 

    public static function whoAmI() { 

     // NOT correct, always gives 'ParentClass' 
     $class = __CLASS__; 

     // NOT correct, always gives 'ParentClass'. 
     // Also very round-about and likely slow. 
     $trace = debug_backtrace(); 
     $class = $trace[0]['class']; 

     return $class; 
    } 
} 

class ChildClass1 extends ParentClass { 

} 

class ChildClass2 extends ParentClass { 

} 

// Shows 'ParentClass' 
// Want to show 'ChildClass1' 
print ChildClass1::whoAmI(); 
print "\n"; 

// Shows 'ParentClass' 
// Want to show 'ChildClass2' 
print ChildClass2::whoAmI(); 
print "\n"; 

Antwort

2

Nun, da PHP 5.3 in freier Wildbahn weit verbreitet ist, wollte ich eine zusammenfassende Antwort auf diese Frage zusammenstellen, um neu verfügbare Techniken zu reflektieren. Wie in den anderen Antworten erwähnt, hat PHP 5.3 Late Static Binding über ein neues Schlüsselwort static eingeführt. Außerdem ist eine neue get_called_class()-Funktion verfügbar, die nur innerhalb einer Klassenmethode (Instanz oder statisch) verwendet werden kann.

Für die Zwecke der Klasse zu bestimmen, wie in dieser Frage gestellt wurde, die get_called_class() Funktion angemessen ist:

<?php 

abstract class ParentClass { 

    public static function whoAmI() { 
     return get_called_class(); 
    } 

} 

class ChildClass1 extends ParentClass { 

} 

class ChildClass2 extends ParentClass { 

} 

// Shows 'ChildClass1' 
print ChildClass1::whoAmI(); 
print "\n"; 

// Shows 'ChildClass2' 
print ChildClass2::whoAmI(); 
print "\n"; 

Die user contributed notes for get_called_class() einige Beispielimplementierungen umfassen, die durch die Nutzung von in PHP 5.2 als auch funktionieren sollte debug_backtrace().

2

Klassenidentifikation ist oft ein Symptom von nicht gut verstandenem Polymorphismus.

Die Clients von ChildClass1 und ChildClass2 sollten nicht zwischen ihnen unterscheiden müssen.

Es gibt keinen Ort, an dem eine Klasse nach someObject.whoAmI() fragen sollte.

Wann immer Sie das Bedürfnis haben, if someObject.whoAmI() == 'ChildClass1' { do X(someObject) } zu schreiben, sollten Sie der ParentClass wirklich eine X() Methode mit verschiedenen Implementierungen in den verschiedenen ChildClasses hinzufügen.

Diese Art von "Laufzeittypidentifikation" kann fast immer durch richtig polymorphe Klassenentwürfe ersetzt werden.

+0

@ S.Lott Ich stimme völlig zu, dass eine solche Methode eine undichte Abstraktion wäre, wenn sie in realem Code verwendet wird. In diesem Fall ist die Methode nur dazu da, ein verständliches Beispiel zu geben. Ich möchte die Child-Klasse ermitteln, um statische Methoden für die Instanzerstellung verwenden zu können, die von allen Mitgliedern einer Klassenhierarchie gemeinsam genutzt werden und dennoch den entsprechenden Kind-Konstruktor aufrufen. –

1

Ab PHP 5.3 wird es mit der Verwendung der static keyword möglich sein, aber jetzt ist es nicht möglich.

Verwandte Themen