私は親にアクセスする方法を探します、親を呼び出さずにクラスの親関数...うーん、ちょっと奇妙な説明に聞こえるので、例を挙げます:
class myclass
{
public function test() { return 'level 1'; }
}
class myclass2 extends myclass
{
public function test() { return parent::test() . '-level 2'; }
}
class myclass3 extends myclass2
{
public function test() { return parent::test() . '-level 3'; }
}
$example = new myclass3();
echo $example->test(); // should display "level 1-level 2-level 3"
「レベル1-レベル3」を表示して、そのようなことをしたいと思います。
class myclass3 extends myclass2
{
public function test() { return parent::parent::test() . '-level 3'; }
}
私がこれをどのようにできるか考えていますか? (フレームワークの一部であるmyclassとmyclass2を編集することはできません...)
シンプルなソリューション。ルートオブジェクトmyclassを直接使用します。
class myclass3 extends myclass2
{
public function test() { return myclass::test() . '-level 3'; }
}
より一般的なアプローチが必要な場合は、 outis answer をご覧ください。
function get_grandparent_class($thing) {
if (is_object($thing)) {
$thing = get_class($thing);
}
return get_parent_class(get_parent_class($thing));
}
class myclass3 extends myclass2 {
public function test() {
$grandparent = get_grandparent_class($this);
return $grandparent::test() . '-level 3';
}
}
または、 reflection :を使用できます
function get_grandparent_class($thing) {
if (is_object($thing)) {
$thing = get_class($thing);
}
$class = new ReflectionClass($thing);
return $class->getParentClass()->getParentClass()->getName();
}
ただし、達成しようとしている内容によっては、良いアイデアとは言えません。
たぶん、myclass3のメンバーオブジェクトとしてmyclass2を追加し、次のようなコードを試してください。
class myclass3{
myclass2 obj2;
public function test() { return $obj2->callParentTest() . '-level3';}
}
いいえ、これは不可能です。残念ながら、元のクラスを直接参照することはできません。self
またはparent
のみです。
クラス1でテスト関数を直接使用する場合は、クラス1から拡張する必要があります。ポリモーフィズムについて検索してください。
「parent::parent::parent::parent
"class5があるとき??
テストメソッドにlevel
パラメーターを追加できると思います。最初に確認してください。
<?php
class myclass
{
public function test($level)
{
return 'level 1';
}
}
class myclass2 extends myclass
{
public function test($level)
{
return $level >= 2 ? parent::test($level) . '-level 2' : parent::test($level);
}
}
class myclass3 extends myclass2
{
public function test()
{
return parent::test(1) . '-level 3';
}
}
$example = new myclass3();
echo $example->test(); // should display "level 1-level 3"
親を連鎖させることはできません。代わりに、親クラスに$ thisを返すだけのGetParent()メソッドを作成します。
私のアプローチ:コードがある場合:
class A {
protected function method () {
var_dump('A -> method');
}
}
class B extends A {
protected function method () {
var_dump('B -> method');
}
}
class C extends B {
protected function method () {
var_dump('C -> method');
}
}
class C
call method from class A
(だがしかし class B
)コードにリファクタリングします:
<?php
class A {
protected function method () {
$this->methodA();
}
protected function methodA () {
var_dump('A -> method');
}
}
class B extends A {
protected function method () {
var_dump('B -> method');
}
}
class C extends B {
protected function method () {
$this->methodA();
}
}
場合によっては、おそらくルートのメソッドを完全にオーバーライドできます。つまり、親の親のコードを呼び出す代わりに、親の親のメソッドコードをコピーして追加できます。
ルートオブジェクトを取得する演算子はありません。私はこのようなことをします:
class myclass
{
public function getRoot() { return __CLASS__; }
public function test() { return 'level 1'; }
}
class myclass2 extends myclass
{
public function getRoot() { return parent::getRoot(); }
}
class myclass3 extends myclass2
{
public function getRoot() { return parent::getRoot(); }
public function test() {
$grandparent = self::getRoot();
return $grandparent::test() . '-level 3';
}
}
$example = new myclass3();
echo $example->test(); // should display "level 1-level 2-level 3"