На самом деле не ломает SOLID, но просто не очень хорошо продуман.
Для более аккуратного подхода используйте интерфейсы.
Так как не все птицы могут летать, использование метода публичной борьбы isFlying()
для всех птиц представляется довольно расточительным.
Может быть, вы могли бы сделать что-то вроде этого:
Ваш базовый Bird
класс, в котором вы определяете общие свойства и методы для всех птиц.
class Bird {
}
Затем, различные интерфейсы для описания различных возможных поведений подклассов Bird. Некоторые птицы летают, некоторые плавают, некоторые разговаривают, некоторые поют, некоторые ныряют, некоторые могут бежать и т. Д. И т. Д.
Для флаеров:
interface FlyingBird {
function isFlying():bool;
function takeOff();
function land();
function fly($bearing, $distance);
}
Для говорящих:
interface TalkingBird {
function say($something);
}
Исполнители:
interface SingingBird {
function sing(array $notes);
}
Пловцы (вам может понадобиться различать тех, кто плавает на поверхности воды и тех, кто может нырять под поверхность).
interface SwimmingBird {
function isSwimming(): bool;
// etc
}
Для бегунов:
interface RunningBird {
function isRunning(): bool;
// etc
}
Тогда у вас могут быть такие классы, как Parrot
(летает и говорит, но не поет, бегает или плавает)
class Parrot extends Bird implements TalkingBird, FlyingBird {
// todo: actual implementation
}
или Ostrich
(может бегать, но не плавать, петь, разговаривать или летать):
class Ostrich extend Birds implements RunningBird { /* implementation */}
Или даже Penguin
(может плавать, не летать, не бегать, не петь, не разговаривать):
class Penguin extends Bird implements SwimmingBird { /* implementation */ }
и т. Д. И т. Д. Весь @package Ornithology
обретает форму.
Пользователи этих классов должны проверить, реализуют ли экземпляры соответствующие интерфейсы:
if ($birdInstance instanceof FlyingBird && $birdInstance->isFlying()) {
echo "This bird is flying!";
}
Чтобы упростить составление этих классов, вы можете создать некоторые черты:
* 1051 Е.Г. *
trait FlyingBirdTrait {
private $flying = false;
function isFlying():bool {
return $this->flying;
}
function takeOff() {
$this->flying = true;
}
function land() {
$this->flying = false;
}
function fly($bearing, $altitude, $distance) {
if (!$this->isFlying()) {
$this->takeOff();
}
// calculate new position;
}
}
Какие классы типа Parrot
могли бы использовать:
class Parrot extends Bird implements TalkingBird, FlyingBird {
uses FlyingBirdTrait;
// rest of the implementation, etc;
}