2008-09-17 6 views
1

以下は、クラス階層とコードの例です。私が探しているのは、 'ChildClass1'または 'ChildClass2'に静的メソッドwhoAmI()が各子クラスで再実装せずに呼び出されたかどうかを判断する方法です。静的メソッドでターゲットクラスを検出する方法はありますか?

<?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"; 

答えて

2

PHP 5.3が広く公開されているので、私は新しく利用可能なテクニックを反映するために、この質問に対する要約をまとめることにしました。

他の回答と同様に、PHP 5.3ではstaticというキーワードでLate Static Bindingが導入されています。また、クラスメソッド(インスタンスまたは静的)内でのみ使用できる新しいget_called_class()関数も使用できます。この質問に頼まれたとして、get_called_class()機能が適切であるクラスを決定する目的のために

<?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"; 

user contributed notes for get_called_class()はを使用することにより、同様PHP 5.2で動作するはずですいくつかのサンプル実装を含めますdebug_backtrace()

2

クラス識別はよく理解されていない多型の症状です。

ChildClass1とChildClass2のクライアントは、それらを区別する必要はありません。

どのクラスでもsomeObject.whoAmI()について質問する必要はありません。

if someObject.whoAmI() == 'ChildClass1' { do X(someObject) }と書くようになったら、実際にX()メソッドをParentClassに追加して、さまざまなChildClassesのさまざまな実装を実装する必要があります。

この種の「実行時型の識別」は、ほとんどの場合、適切なポリモーフィックなクラス設計に置き換えることができます。

+0

@ S.Lott私は、そのようなメソッドが実際のコードで使用された場合、漏れやすい抽象であることに完全に同意します。この場合、方法は理解できるサンプルを提供するだけです。子クラスを決定したい理由は、クラス階層のすべてのメンバーが共有する静的インスタンス作成メソッドを利用できるようにするためですが、まだ適切な子コンストラクタを呼び出しています。 –

1

PHP 5.3以降では、static keywordを使用することができますが、現在のところ不可能です。

関連する問題