Автозапчасти могут быть интересными, например, Вы могли бы иметь
class part
{
OEM
Manufacturer
Number
Description
}
class Tire extends Part
{
Speed
Rating
}
Уродливым обходным решением было бы передать Папе логический параметр, указывающий, что вы не хотите анализировать код, содержащийся в его конструкторе. то есть:
// main class that everything inherits
class Grandpa
{
public function __construct()
{
}
}
class Papa extends Grandpa
{
public function __construct($bypass = false)
{
// only perform actions inside if not bypassing
if (!$bypass) {
}
// call Grandpa's constructor
parent::__construct();
}
}
class Kiddo extends Papa
{
public function __construct()
{
$bypassPapa = true;
parent::__construct($bypassPapa);
}
}
В итоге я придумал альтернативное решение, которое решило проблему.
Я поддержал два других ответа, которые предоставили действительные, но уродливые решения для более уродливого вопроса :)
Другой вариант, который не использует флаг и может работать в вашей ситуации:
<?php
// main class that everything inherits
class Grandpa
{
public function __construct(){
$this->GrandpaSetup();
}
public function GrandpaSetup(){
$this->prop1 = 'foo';
$this->prop2 = 'bar';
}
}
class Papa extends Grandpa
{
public function __construct()
{
// call Grandpa's constructor
parent::__construct();
$this->prop1 = 'foobar';
}
}
class Kiddo extends Papa
{
public function __construct()
{
$this->GrandpaSetup();
}
}
$kid = new Kiddo();
echo "{$kid->prop1}\n{$kid->prop2}\n";
Вы можете посмотреть это видео от службы технической поддержки Google, в котором объясняются передовые методы кодирования JavaScript, которое является основной частью разработки расширений Firefox
Хорошо, еще одно уродливое решение:
Создайте функцию в Papa, например:
protected function call2Granpa() {
return parent::__construct();
}
Затем в Kiddo вы используете:
parent :: call2Granpa ();
// вместо вызова конструктора в Папе.
Думаю, это может сработать ... Я не тестировал это, поэтому не уверен, правильно ли созданы объекты .
Я использовал этот подход, но с функциями, не являющимися конструкторами.
Для этого есть более простое решение, но оно требует, чтобы вы точно знали, через какое количество наследований прошел ваш текущий класс. К счастью, аргументы get_parent_class () позволяют члену вашего массива класса быть именем класса в виде строки, а также самим экземпляром.
Имейте в виду, что это также по своей сути основано на статическом вызове метода __construct () класса, хотя в пределах экземпляра области видимости наследующего объекта разница в этом конкретном случае незначительна (ах, PHP).
Примите во внимание следующее:
class Foo {
var $f = 'bad (Foo)';
function __construct() {
$this->f = 'Good!';
}
}
class Bar extends Foo {
var $f = 'bad (Bar)';
}
class FooBar extends Bar {
var $f = 'bad (FooBar)';
function __construct() {
# FooBar constructor logic here
call_user_func(array(get_parent_class(get_parent_class($this)), '__construct'));
}
}
$foo = new FooBar();
echo $foo->f; #=> 'Good!'
Опять же, это не жизнеспособное решение для ситуации, когда вы не знаете, сколько наследования произошло, из-за ограничений debug_backtrace (), но в контролируемых обстоятельствах это работает как предполагалось.