Вопрос

Я пытаюсь заставить работать следующее, но я в растерянности...

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();

}

}

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top