Для чого потрібен поліморфізм можна обійтися без нього

Поліморфізм - це техніка використання механізму пізнього зв'язування і успадкування.

Пізніше зв'язування означає, що вибір конкретного типу змінної відбувається під час роботи програми, а не задається програмістом явно.

Ну наприклад, ти пишеш гру в якій є город і різні види овочів - моркви, капусти і т.п. Юзер буде садити ці овочі в довільному порядку, ти не знаєш порядок на етапі написання програми, тому ти не можеш написати щось типу:

carrot_obj-> grow (); // просиш конкретну морквину підрости

Є різні способи вивернутися і вирішити проблему в цій ситуації, але найлаконічніший з них - це поліморфізм.

Пізніше зв'язування виконує визначення конкретного типу (виду овоча) на етапі виконання, а на етапі компіляції ти повинен зв'язати всі види овочів з більш загальним типом. Тому поліморфізм - це спадкування + пізніше зв'язування. Найбільш загальний клас

повинен описувати інтерфейс для всіх наших овочів:

virtual int grow () = 0; // метод змушує абстрактний овоч рости

Саме через цей інтерфейс при використанні поліморфізму ми звертаємося до конкретних класах овочів (вибір конкретного класу виконується автоматично в залежності від типу об'єкта, який прихований за цим інтерфейсом:

class Carrot. public Fruit

class Potato. public Fruit

При такому розкладі, наш город повинен містити список овочів (абстрактних):

при цьому в С ++ для використання пізнього зв'язування треба застосовувати покажчики (або розумні покажчики якщо не хочемо мучитися з витоками пам'яті), а в Java і С #, наприклад, все буде зроблено автоматично, тому що там повсюдно використовується ідіома PIMPL (там завжди всюди розумні покажчики).

Припустимо, користувач перетягне морквину в свій город. При цьому буде створено нову морквина (будь-яким чином - я навів приклад з явним викликом конструктора, але це могло б бути і що то типу шаблону Prototype) і додана в список овочів.

Fruit * obj = new Carrot ();

Потім, в цей список могли б додаватися у хаотичному порядку інші овочі, а якийсь код з певною періодичністю виконував зростання цих овочів:

for (i = 0; i При цьому якщо i-тий об'єкт масиву фруктів був створений як морквина, то буде виконуватися код Carrot :: grow (), а якщо як картопля - то Potato :: grow (). Програмісту тепер не треба паритися з цим, функція потрібного типу буде посдавлена ​​автоматично під час виконання.

система вибрала цю відповідь найкращим

Схожі статті