Можно ли так у конструктора задавать параметры и не противоречит ли это принципу Барбары Лисков?

Ссылка скопирована
1 ответ

Всем привет.
Погружаюсь в ООП и возник вопрос по созданию дочернего класса.

Есть родительский класс

class Animal {     public function __construct(         public string $name,         public int $health,         public int $power,         public bool $alive = true     ) {     }      public function calcDamage() {         return $this->power * (mt_rand(100, 300) / 200);     }      public function applyDamage(int $damage) {         $this->health -= $damage;          if($this->health <= 0) {             $this->health = 0;             $this->alive = false;         }     } }

class Animal { public function __construct( public string $name, public int $health, public int $power, public bool $alive = true ) { } public function calcDamage() { return $this->power * (mt_rand(100, 300) / 200); } public function applyDamage(int $damage) { $this->health -= $damage; if($this->health <= 0) { $this->health = 0; $this->alive = false; } } }

Я от него наследуюсь и создаю следующий класс

class Mouse extends Animal {     private float $hiddenLevel;     public function __construct(         public string $name,         public int $health,         public int $power     ) {         parent::__construct(name: $name, health: $health, power: $power);         $this->hiddenLevel = 0.4;     } }

class Mouse extends Animal { private float $hiddenLevel; public function __construct( public string $name, public int $health, public int $power ) { parent::__construct(name: $name, health: $health, power: $power); $this->hiddenLevel = 0.4; } }

И вот тут у меня вопрос на счет конструкторов родителя и дочернего класса. Принцип Барбары Лисков гласит, что родитель может быть замещен ребенком без потери работоспособности кода (надеюсь я правильно понял этот принцип). И как я понимаю, конструктор ребенка должен совпадать с конструктором родителя.

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

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

Заранее благодарю.

P.S. Абстрактные классы и интерфейсы сейчас не рассматриваю, т.к. пытаюсь лучше разобраться в таких маленьких нюансах.

Дополнительно:

LSP относится не к классам, а к объектам. Что у дочернего класса "под капотом", как он создается и действует вне реализации методов и свойств базового класса - это его личное дело.

С одной стороны, конструктор - часть интерфейса класса. С другой - никакой внешний код не сможет вызвать конструктор дочернего класса, ничего о нем не зная. А принцип применяется именно для того, чтобы внешний код мог ничего не знать о дочерних классах. Так что соблюдать LSP в конструкторе - просто бессмысленно.

  • Понял, спасибо за ответ)

Ответы:

Любые принципы вот эти - они абстрагированы от языка. Язык сверху накладывает на них ограничения. Поэтому 100% следования принципам не получается в общем смысле.

Поэтому мне кажется, вы сильно дословно восприняли рекомендации. Этот принцип не означает что можно взять и просто заменой (текстовой) поменять родителя на ребенка и все соберется без ошибок.
Это означает что ЛОГИЧЕСКИ можно заменить один класс на другой и ЛОГИЧЕСКИ ничего не сломается (а не будет ошибка компилятора)

И конкретно в вашем случае этот принцип не выполнится. Потому что если будет где то создание мертвого животного - на мышь вы его просто так не замените - логика отвалится.

  • Согласен с вами, единственное у меня вопрос про передачу параметров в конструкторе) Остальное понимаю, что SOLID, GRASP и т.д. - набор рекомендаций, а не строгих правил)

Смысл в том, что бы не поломалось поведение в потомке.

class Mouse extends Animal {     public function calcDamage() {         throw new Exception('Мышь не наносит урон');     } }

class Mouse extends Animal { public function calcDamage() { throw new Exception('Мышь не наносит урон'); } }

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Юрий Linux Ответ

Да, конструктору можно задавать параметры. В языке программирования PHP конструктор класса может иметь параметры, которые передаются при создании экземпляра объекта. Эти параметры могут быть использованы для инициализации объекта в момент его создания.

Принцип Барбары Лисков (Liskov Substitution Principle) гласит, что объекты должны быть заменяемыми на экземпляры их подтипов без изменения корректности программы. То есть, подклассы должны быть взаимозаменяемы с их суперклассами.

Если конструктор класса принимает параметры, это не противоречит принципу Барбары Лисков, поскольку конструктор является частью класса и отвечает за инициализацию объекта. Параметры конструктора могут быть использованы для передачи данных, необходимых для корректной инициализации объекта.

Пример использования параметров в конструкторе класса в PHP:

class Person {
    private $name;
    private $age;
 
    public function __construct($name, $age) {
        $this->name = $name;
        $this->age = $age;
    }
 
    public function getName() {
        return $this->name;
    }
 
    public function getAge() {
        return $this->age;
    }
}
 
$person = new Person("John Doe", 30);
echo $person->getName(); // выводит "John Doe"
echo $person->getAge(); // выводит 30

class Person { private $name; private $age; public function __construct($name, $age) { $this->name = $name; $this->age = $age; } public function getName() { return $this->name; } public function getAge() { return $this->age; } } $person = new Person("John Doe", 30); echo $person->getName(); // выводит "John Doe" echo $person->getAge(); // выводит 30

Таким образом, использование параметров в конструкторе класса в PHP является допустимым и не противоречит принципу Барбары Лисков, если это не нарушает заменяемость объектов и их подтипов.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно