PHP вызывает метод родительского класса - PullRequest
0 голосов
/ 22 мая 2018
class Foo {
    protected static $a = 1;
    protected $b = 2;

    public function func() { return 'foo' . static::$a . $this->b; }
}
class Bar extends Foo {
    protected static $a = 3;
    protected $b = 4;

    public function func() { return 'bar' . static::$a . $this->b; }
}

$obj = new Bar();
$obj->func(); // returns of course 'bar34'

Есть ли в PHP какая-либо опция для вызова func () из класса Foo?В C ++ я бы приводил $ obj к Foo и просто вызывал бы func ()

Bar* obj = new Bar();
Foo* obj2 = (Bar*) obj;
obj2->func(); // returns 'foo14';

Ответы [ 4 ]

0 голосов
/ 22 мая 2018

Если вы хотите разобраться с Reflection, тогда это возможно, но я бы настоятельно сказал, что это не должно использоваться где-либо рядом с любым рабочим кодом.Если у вас есть экземпляр дочернего класса, значит, у вас есть причина, а если он переопределил родительский метод, то это также произошло по причине.

Если вы уже знаете все этозатем, с учетом этого отказа от ответственности, это должно работать в любой удаленно последней версии PHP:

class Foo { public function func() { echo 'I am the parent'; } }
class Bar extends Foo { public function func() { echo 'I am the child'; } }

// Create instance of child class
$bar = new Bar;

// Create reflection class
$reflected = new ReflectionClass(get_class($bar));

// Get parent method
$method = $reflected->getParentClass()->getMethod('func');

// Invoke method on child object
$method->invokeArgs($bar, []);

// I am the parent

См. https://3v4l.org/NP6j8

0 голосов
/ 22 мая 2018

Не знаю, должно ли это помочь вам, но попробуйте добавить эту функцию в класс Bar

public function callParent($function){
    return parent::$function();
}

и вызвать

echo $obj->callParent("func");

[ОБНОВЛЕНО] Также вы можете написать функцию приведениясам как то так

public function castAs($newClass) {
    $obj = new $newClass;
    foreach (get_object_vars($this) as $key => $name) {
        $obj->$key = $name;
    }
    return $obj;
}
0 голосов
/ 22 мая 2018

Для меня это больше похоже на проблему дизайна.Однако, если бы я справился с этим способом, который был бы легко читаем и без переосмысления моего дизайна, я бы сделал:

<?php
class Foo {
    public function func() { return 'foo'; }
}
class Bar extends Foo {
    public function func() { return 'bar'; }
    public function parentFunc() { return parent::func(); }
}

$obj = new Bar();
$obj->parentFunc(); // returns of course 'foo'

Ответ Лука также работает, но не вызывает метод для родительского объекта.Он просто вызывает метод для родительского класса.Все зависит от функциональности, которую вы ищете.

Вы также можете сделать что-то вроде:

<?php
class Foo {
    public function func() { return 'foo'; }
}
class Bar extends Foo {
    public function func($parent = false) { 
        if ($parent) {
            return parent::func();
        }
        return 'bar';
    }
}

$obj = new Bar();
$obj->func(true); // returns of course 'foo'

Что похоже, но без необходимости дополнительного метода.

Лично мне кажется, что эта проблема, скорее всего, требует переосмысления в дизайне кода, а не решения для кодирования.

- edit -

Чтобы подробнее остановиться на «переосмыслении в дизайне кода», я быСпросите себя: «Зачем мне нужен объект, у которого есть два метода с одинаковым именем, но разными функциональными возможностями? Разве это не работа для двух разных объектов? Отслеживайте проблему в обратном направлении, пока не найдете проблему проектирования. Или точку, в которой принимается решение».необходимо указать, какой объект требуется вашей структуре.

0 голосов
/ 22 мая 2018

Это не совсем то, что я бы назвал довольно, но это работает и относительно похоже на то, что вы описали для C ++;Он работает, вызывая get_parent_class() и затем злоупотребляя способностью PHP создавать объекты из строк.

<?php

class Foo {
    public function func() { echo 'foo'; }
}
class Bar extends Foo {
    public function func() { echo 'bar'; }
}

$obj = new Bar();
$obj->func(); // Prints 'bar'

$parentClassString = get_parent_class($obj);
$newObj = new $parentClassString; // Gotta love PHP for magic like this
$newObj->func(); // Prints 'foo'

См. этот фрагмент , чтобы увидеть его в действии.

РЕДАКТИРОВАТЬ

Это большая работа, но вы можете использовать так называемое Позднее статическое связывание , возможно, более четко объясненное в Ответ Джокериуса здесь.Это требует от вас написания дерьмового кода, хотя я не считаю его предпочтительным.В целом, короткий ответ выглядит так: на самом деле это невозможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...