РЕДАКТИРОВАТЬ: очень жаль облажался оригинальный пример. Больше объяснения в конце.
Я новичок в ООП, находя это полезным, находя это запутывающим.
Я посмотрел, и я думаю, что это, должно быть, простой вопрос, но искал такие вещи, как «создание экземпляров подкласса php», но ничего не смог найти на месте.
Я хочу создать экземпляр объекта, а затем создать экземпляр подкласса. Могу ли я «добавить» подкласс в существующий экземпляр?
class Dog
{
protected $owner;
protected $color;
public function setOwner($owner)
{
$this->owner = $owner;
}
public function setColor($color)
{
$this->color = $color;
}
}
class Bulldog extends Dog
{
protected $name;
protected $typeOfTail;
... set tail....
public function setName($name)
{
$this->name = $name;
}
}
class Beagle extends Dog
{
protected $name;
protected $typeOfSpots;
... set spots ....
public function setName($name)
{
$this->name = $name;
}
}$myDog = new Dog;
$myDog -> setOwner("Bob");
$myDog1 = new Beagle;
$myDog1 -> setName("name");
Очевидно, что это не будет работать, но если я сделаю
$myDog = new Beagle;
$myDog -> setName("name");
Я предполагаю, что просто устанавливает владельца на NULL?
Есть ли способ вытащить существующие значения (или дублировать значения) класса и экземпляр подкласса (я полагаю, я мог бы сделать какой-то сложный метод для извлечения всех значений, но их много … .) Это что-то легко сделать в PHP, или я на LIMB?
Сейчас 3:30, и я прошу прощения, если это действительно глупо, но я врезался в стену в последние пару дней и отстаю. Кажется, это может быть полезно в текущем проекте.
Разъяснение: Это гипотетический пример. (Нет собак, вовлеченных в проект.) Скажем, у нас есть коричневая собака, принадлежащая Фреду, и мы заполняем случай dog
(притвориться, что это большой класс с большим количеством продолжающихся).
На следующий день кто-то говорит: «эта собака — бигль» (хорошо, позже в файле — это не хороший пример), поэтому мы хотим создать экземпляр Beagle
класс с именем суки.
То, что я хочу, это пример Beagle
что наследует уже существует dog
Информация.
Извините еще раз. Идти спать.
Общее решение: (на случай, если вы уже знаете будущий подкласс)
Просто создайте экземпляр подкласса напрямую. Вы можете использовать его как экземпляр суперкласса. Но было бы полезно получить дополнительную информацию о том, чего вы пытаетесь достичь.
Так что это будет работать так:
class Dog
{
protected $owner;
protected $color;
public function setOwner($owner)
{
$this->owner = $owner;
}
public function setColor($color)
{
$this->color = $color;
}
}
class Beagle extends Dog
{
protected $name;
public function setName($name)
{
$this->name = $name;
}
}$myDog = new Beagle;
// here we call two methods of the Dog superclass
$myDog->setOwner("Bob");
$myDog->setColor("brown");
// now we call a method of the subclass
$myDog->setName("SomeName");
Как вы можете видеть, нет необходимости снова добавлять методы родительского класса в подкласс. Они будут наследоваться неявно, и вы можете просто использовать их в экземплярах подклассов, как если бы они были определены в подклассе.
Если вы пропустите один из этих вызовов метода, свойство будет null
потому что никакое значение по умолчанию не назначено свойствам.
Конкретное решение: (в случае, если вы не знаете фактический подкласс)
Если вы не можете создать подкласс напрямую, создайте конструктор следующим образом:
class Dog
{
protected $owner;
protected $color;
public function __construct(Dog $dog = null) {
if ($dog) {
foreach ($dog as $key => $value) {
if (property_exists($this, $key)) {
$this->{$key} = $value;
}
}
}
}
public function setOwner($owner)
{
$this->owner = $owner;
}
public function setColor($color)
{
$this->color = $color;
}
}
class Beagle extends Dog
{
protected $name;
public function setName($name)
{
$this->name = $name;
}
}
$dog = new Dog;
$dog->setOwner("Bob");
$beagle = new Beagle($dog);
$beagle->setColor("brown");
Я не тестировал код, так что, возможно, в нем все еще есть ошибка, но она должна получить мою точку зрения.
Родительские и дочерние классы
Вы можете создать 2 класса, давайте назовем один ParentClass
и один ChildClass
, Это дает нам:
class ParentClass
{
}
class ChildClass
{
}
Как вы можете видеть, они не связаны каким-либо образом, формой или формой, поэтому нам нужно простираться дочерний класс для использования родителя, поэтому теперь у нас есть:
class ParentClass
{
}
class ChildClass extends ParentClass
{
}
Теперь ребенок говорит с родителем, поэтому давайте добавим свойство к родителю, давайте вызовем его name
:
class ParentClass
{
protected $name; //Protected means it's private, but accessible to children
}
class ChildClass extends ParentClass
{
}
Теперь давайте добавим некоторые функциональные возможности для дочернего элемента, метода получения и установки:
class ParentClass
{
protected $name;
}
class ChildClass extends ParentClass
{
public function setName($value)
{
$this->name = $value;
}
public function getName()
{
return $this->name;
}
}
Как видите, он использует $name
от родителя, то есть это значение доступно для ребенка, поэтому мы можем сделать:
$childClass = new ChildClass();
$childClass->setName("My Name");
print $childClass->getName(); // prints My Name
И получите результат!
редактировать
Дополнительно, чтобы показать дифференциацию в сеттерах:
class Dog
{
protected $owner;
protected $color;
protected $name; // I'd put this here as all dogs have a name, right?
// Put the getters in here as all they do is return, they won't change (hopefully...)
public function getOwner()
{
return $this->owner;
}
public function getColor()
{
return $this->color;
}
public function getName()
{
return $this->name;
}
}
class Beagle extends Dog
{
public function setOwner($val)
{
$this->owner = $val;
}
public function setColor($val)
{
$this->color = $val;
}
public function setName($val)
{
$this->name = $val;
}
}
/**
* Added extra code to setters
*/
class Dalmatian extends Dog
{
public function setOwner($val)
{
$this->owner = "Owner: " . $val;
}
public function setColor($val)
{
$this->color = "Color: " . $val;
}
public function setName($val)
{
$this->name = "Name: " . $val;
}
}
Как вы можете видеть в этом примере, есть 2 дочерних класса, Beagle
а также Dalmatian
, каждый с несколько различными установщиками для значений.
Поскольку значения не являются статическими в родительском классе, они будут разными для каждого дочернего класса, поэтому установка одного не изменит другого, и наоборот.
Чтобы сохранить значения от родителя во всех подклассах, используйте статические свойства как таковые:
class Dog
{
protected static $owner;
protected static $color; // Don't know why you'd want this kept, but okay?
}
И звоните используя static::${variable_name};
в отличие от: $this->{variable_name};