В чем косяк (полиморфизм)?

Недавно ходил на собеседование и и меня попросили рассказать , что такое полиморфизм.
Ответил следующие.

class unit {
    public $hp = 'NaN';
    public function setHp (){
			return $this->hp = "30 hp";
    }
}
class warrior extends unit {
     public function setHp (){
         return $this->hp = "80 hp";
     }
}
class medic extends unit {
    public function setHp (){
        return $this->hp = "40 hp";
    }
}
class tank extends unit {
    public function setHp (){
        return $this->hp = "200 hp";
    }
}

$warrior = new warrior;
$medic = new medic;
$tank = new tank;
$unit = new unit;

echo $warrior->setHp();
echo $medic->setHp();
echo $tank->setHp();
echo $unit->setHp();

Тот , кто мне собеседовал , сказал , что это не правильно . ( гуглил в инете везде подобных примеров полным полно). В чем я ошибаюсь ?
  • Вопрос задан
  • 723 просмотра
Пригласить эксперта
Ответы на вопрос 4
@xfg
В программировании несколько различных видов полиморфизма. Вам следовало уточнить, о каком из них идет речь. Собеседующий с вами конечно же не совсем корректен, так как простейшая форма полиморфизма в вашем примере все же присутствует. Другое дело, что в php под полиморфизмом обычно понимают полиморфизм подтипов. Выглядит так
interface UnitInterface {
  public function setHp();
}
class Warrior implements UnitInterface {
  public function setHp() {...}
}
class Medic implements UnitInterface {
  public function setHp() {...}
}

class MainProgram {
  private $unit;

  public function __construct(UnitInterface $unit) {
    $this->unit = $unit;
  }
  public function run() {
    return $this->unit->setHp();
  }
}

echo (new MainProgram(new Warrior())->run();

Идея в том, что конструктор класса MainProgram ничего не знает о конкретных реализациях ваших юнитов. Он знает только о том, что они должны удовлетворять интерфейсу UnitInterface. В будущем если у вас хорошо спроектирован интерфейс, то вы сможете заменить одну реализацию юнита на другую, не изменяя код внутри MainProgram. Таким образом, вы соблюдаете принцип открытости/закрытости из SOLID, который говорит, что классы должны быть открыты для расширения, но закрыты для изменений.
Ответ написан
TheTalion
@TheTalion
Может стоило сделать абстрактным метод в unit, а потом его переопределять? Т.к. юнита отдельно мы не используем, поэтому реализацию функции для него нам знать не нужно. Нужно знать только наличие функции.
Ответ написан
Комментировать
Sanasol
@Sanasol Куратор тега PHP
нельзя просто так взять и загуглить ошибку
return $this->hp = "200 hp";
Конструкция какая-то неизвестная миру.
Почему return везде?
Почему возвращается присваивание?

Ну и логичнее наверно делать unit interface, а не класс.
Ответ написан
rdifb0
@rdifb0
Программист, реалист
Если в вопросе предполагался параметрический полиморфизм, то его нужно было показать. Вы показали только наследование и создание объектов. Нужно было хотя бы загнать их в массив и в цикле делать setHp(). Тем самым показать что все равно какой там тип. unit можно заменить на интерфейс, и сделать какую-то внешнюю функцию которая бы требовала этот интерфейс, а вы туда передавали бы воинов и танков.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы