начал разбираться с полиморфизмом и нашел следующий пример:
есть класс Soldier, и General - его наследник. У первого есть метод getHealth(), у второго - getSlogan()
Не понятен принцип создания объекта класса.
Есть следующие строчки кода:
Soldier warrior1 = new Soldier();
General warrior2 = new Soldier();
Soldier warrior3 = new General();
Как происходит создание объекта. В первой строчке ми создаем объект типа солдат, правильно? Тогда во второй выбьет ошибку, а третья создаст солдата и приведет к генералу? Почему так и когда надо подобное приведение ведь проще сразу создать генерала типа генерал.
И второй вопрос ориентируясь по третей строчке я не могу применить warrior3.getSlogan(),только warrior3.getHealth() ? А если бы метод getSlogan() был в солдате, то такой вызов был бы возможен? И это благодаря полиморфизму?
Ответ
Давайте начнем с понятия полиморфизм. Полиформизм - это такой свойство в данном случае метода, когда один и тот же метод ведет себя по разному.
Возмем пример из жизни. Есть класс Животное. Есть класс Утка, которая насаледутся от Животное. Есть еще один класс Собака, которое тоже наследуется от Животное.
Животное это абстракция, где мы можем просто определить метод Голос(). Мы его объявим абстрактным или виртуальным. Зависит от языка. Живтоных много, и каждый класс Утка и Собака будут иметь свои реализации для метода Голос()
Теперь когда мы можем создать Утку и Собаку и привести их к Живтоному.
Псевдо код будет выглятеть так:
Живтоное animals[2];
animals[0] = new Утка();
animals[1] = new Собака();
for (animal in animals) {
animal.Голос();
}
Т.е. при вызове метода Голос() мы не знаем реально, с каким объектом мы имеем дело, но можем вызвать именно его реализацию. В этом вся сила полиморфизма.
Теперь ко вопросу про доступные методы. Тип переменной animal определяет доступные методы. Именно поэтому ни один метод из класса Утки не известен классу Животное
Приведение типов. Это отдельная большая тема. У нас есть возможно приводить типы двигаясь вверх или вниз по дереву наследования. Замечу, что двигаться вниз безопаснее в силу того, что мы знаем текущий тип объекта и можем точно знать от кого он наследуюется. Движение же верх (от абстракции к конкретике) более опасно и именно тут лучше использовать явное приведение типа, что бы подсказать компилятору. Все конечно зависит от языка. В вашем случае приведение к типу генерал невозможно т.к. объекта генерал в принцепе не существует. Есть только объект типа Солдат
Я очень рекомендую для начала разобраться в понятиях объект и тип. Тогда многое в ООП станет более понятным.
Комментариев нет:
Отправить комментарий