Классы PHP5:наследование составного класса?
-
13-09-2019 - |
Вопрос
Я пытаюсь заставить работать следующее, но я в растерянности...
class Foo {
public $somethingelse;
function __construct() {
echo 'I am Foo';
}
function composition() {
$this->somethingelse =& new SomethingElse();
}
}
class Bar extends Foo {
function __construct() {
echo 'I am Bar, my parent is Foo';
}
}
class SomethingElse {
function __construct() {
echo 'I am some other class';
}
function test() {
echo 'I am a method in the SomethingElse class';
}
}
Что я хотел бы сделать, так это создать экземпляр класса SomethingElse внутри класса Foo.Это работает с помощью =&
.Но когда я расширил класс Foo с помощью класса Bar , я подумал, что дочерний элемент наследует все атрибуты данных и методы от родительского класса.Однако, похоже, что $this->somethingelse
не работает в панели дочерних классов:
$foo = new Foo(); // I am Foo
$foo->composition(); // I am some other class
$foo->somethingelse->test(); // I am a method in the SomethingElse class
$bar = new Bar(); // I am Bar, my parent is Foo
$bar->somethingelse->test(); // Fatal error: Call to a member function test() on a non-object
Итак, разве невозможно наследовать таким образом?И должен ли я создать новый экземпляр класса SomethingElse изнутри class Bar, если я хочу использовать его там?Или я что-то упускаю?
Заранее благодарю за вашу помощь.
Решение
Я думал, что дочерний элемент наследует все атрибуты данных и методы родительского класса.
Это правда — дочерний класс наследует статические переменные и статические методы родительского класса.Кроме того, любые дочерние объекты будут наследовать статические переменные и переменные и методы экземпляра.
Одна из возможностей получить то, что вы хотите, с существующей структурой классов заключается в следующем:
$bar = new Bar();
$bar->composition();// here you are calling the parent method, sets instance var $somethineelse
$bar->somethingelse->test();// now you can call methods
Другой способ наследования переменной (в данном случае объекта) в дочерних экземплярах может быть таким:
class Foo {
protected $somethingelse;
public function __construct() {
$this->somethingelse = new SomethingElse();
}
}
class Bar extends Foo {
public function __construct() {
parent::__construct();
// now i've got $somethingelse
}
}
Очень хороший обзор классов и объектов в PHP 5 можно найти здесь:http://php.net/manual/en/language.oop5.phpОбязательно прочитайте все это, может быть, пару раз, если ООП для вас новичок.
Другие советы
bar имеет переменную-член с именем Somethingelse, которая унаследована от foo.
вы смешиваете область объекта и класса.
если вы действительно хотите добиться описанного эффекта, вам нужно сделать переменную статической, чтобы ее контекст был основан на классе.
Во-первых, вы должны различать статические переменные и переменные экземпляра.Статические переменные являются общими для всех экземпляров класса, переменные экземпляра - нет.
Если вы хотите, чтобы каждый экземпляр Foo и Bar имел точно такой же экземпляр SomethingElse, вы должны сделать $somethingelse статичным:
публичный статический $somethingelse
и вам следует изменить композицию-функцию Foo:
function composition() {
self::$somethingelse = new SomethingElse();
}
Чтобы получить доступ к этому статическому полю, вы можете сделать следующее:$foo = новый Foo();// Я Foo $foo-> композиция();// Я какой-то другой класс Foo:$somethingelse->test();// Я являюсь методом в классе SomethingElse
$bar = новый бар();// Я Bar, мой родитель Foo Bar::$somethingelse-> тест ();// Я являюсь методом в классе SomethingElse
Если вы хотите, чтобы каждый экземпляр Foo и Bar имел свой собственный экземпляр SomethingElse, вы можете использовать свой код, но вам нужно добавить
$bar->композиция()
перед $bar->somethingelse->test();
Это потому, что с
$bar = новый бар();
вы создали совершенно новый экземпляр Bar, и у этого экземпляра есть свойство $somethingelse, но оно еще не было установлено.Поэтому вам нужно вызвать composition (), чтобы установить его.
Если каждый Foo и Bar должен иметь точно такой же экземпляр SomethingElse, вам следует использовать статическую версию вместо этого, потому что это уменьшает объем необходимой памяти.
Я надеюсь, что это поможет вам.В противном случае я буду очень рад объяснить это подробнее.
Утверждение о том, что классы имеют общие атрибуты, не означает, что объекты имеют общие атрибуты. значения атрибутов.
Как отмечали другие, вы путаете классы с экземплярами.
Обратите внимание: если вы это сделаете, вы получите ту же ошибку:
$foo = new Foo(); // I am Foo
$foo->composition(); // I am some other class
$foo->somethingelse->test(); // I am a method in the SomethingElse class
$foo2 = new Foo(); // I another Foo
$foo2->somethingelse->test(); // Fatal error: Call to a member function test() on a non-object
Думайте о занятиях менее абстрактно.Например, у вас может быть класс «Человек», который является родительским классом «Роялти».
Тогда, если вы это сделали:
$me = новый человек();$me->firstName = "Томас"
$princeCharles = новый роялти();
Вы не хотели бы, чтобы $princeCharles имел атрибут firstName, равный «Thomas», и если вы хотите установить $princeCharles->firstName, вам не нужно этого делать, чтобы изменить значение атрибута firstName $me.
И $me, и $princeCharles имеют атрибут firstName, но у нас нет общего атрибута. ценить этого атрибута.
Я думаю, ваша проблема будет решена, если в производном классе конструктор вызовет конструктор родительского класса.Это не происходит по умолчанию в PHP, поэтому имейте это в виду, если у вас возникнут проблемы с наследованием элементов данных.
класс Bar расширяет Foo { общедоступную функцию __construct() { родительский элемент::__construct();
}
}