Начнём с определения в википедии:
Полиморфизм в языках программирования и теории типов — способность функции обрабатывать данные разных типов
Существует два вида полиморфизма ad-hoc (он же мнимый) и параметрический (он же истинный). Язык Dart не поддерживает перегрузку (overloading) метода поэтому обсуждать ad-hoc нет смысла. Переходим к параметрическому полиморфизму и сразу смотрим на примере.
Создадим класс Teacher с 2-мя свойствами yearExpiriance - опыт в годах и birthYear - год рождение. Метод study где будем возвращать текст - Я уже обучаю студентов Х лет. А так же сеттор age - с помощью него будем устанавливать новую дату рождения и геттер - будем определять на сколько большой опыт преподавания у учителя.
class Teacher { final int yearExperience; late int yearBirth; Teacher({required this.yearExperience, required this.yearBirth}); String study() { return 'I am teacher'; } // Раскоментируйте, чтоб убедиться что перегрузку методов Дарт не поддерживает. // Вы получите ошибку - The name 'study' is already defined. // String study(int any) { // return 'I study my students for $yearBirth'; // } set age(int val) => yearBirth = (DateTime.now().year - val); String get isBigExpiriance => yearExperience >= 10 ? 'Опыт больше или равен 10 лет' : 'Опыт меньше 10 лет'; }
Полиморфизм в ООП не может существовать без наследования!
Создаём два класса, EnglishTeacher - учитель английского языка, который будет наследоваться о�� Teacher и класс ChildrenEnglishTeacher (детский учитель английского языка), который будет наследоваться от EnglishTeacher.
import 'package:flutter_application_1/teacher.dart'; class EnglishTeacher extends Teacher { EnglishTeacher({required super.yearExperience, required super.yearBirth}); // Переопределяем метод базового класса. @override String study() { return 'I have been teaching my students for $yearExperience years'; } String hasLessonsToday() { return 'Yes. I have lesson today'; } // Переопределяем метод базового класса. @override String get isBigExpiriance => yearExperience >= 5 ? 'Большой опыт' : 'Опыт учителя английского языка $yearExperience года'; }
Класс EnglishTeacher с помощью @override переопределяет метод study базового класса (Teacher) и будет возвращать другой текст, специфичный для учителя английского языка (Я обучаю моих студентов уже Х лет). А так же EnglishTeacher имеет собственный метод hasLessonsToday, который отвечает на вопрос: "Есть ли сегодня занятия?" и будет возвращать - "Да. Сегодня будет занятие". А так же мы, переопределили геттор isBigExpiriance, где изменили условия и тексты.
Класс ChildrenEnglishTeacher мы создадим, просто для того чтоб было понимание что можно построить иерархию классов, где каждый последующий класс будет наследоваться от вышестоящиего. И в самом нижнем классе всегда можно переопределить методы из всех вышестоящих в плоть то самого верхнего (базового Teacher). То есть метод hasLessons есть в классе EnglishTeacher, но его нет в базовом классе (самый верхний -Teacher).
А так же у нас есть возможность переопределить сеттор age который есть у самого верхнего базового класса Teacher.
import 'package:flutter_application_1/english_teacher.dart'; class ChildrenEnglishTeacher extends EnglishTeacher { ChildrenEnglishTeacher( {required super.yearExperience, required super.yearBirth}); @override String hasLessonsToday() { return 'No. I have not'; } @override set age(int val) => yearBirth = (DateTime.now().year - val - 3); }
Теперь приступим к проверке, в функции main сделаем инстанс EnglishTeacher и запустим оба унаследованных от базового класса метода
void main() { final englishTeacher = EnglishTeacher(yearExperience: 5, yearBirth: 1970); print(englishTeacher.study()); print(englishTeacher.isBigExpiriance); }
Вывод в консоль

И проверим наш самый низший класс наследник ChildrenEnglishTeacher
void main() { final childrenEnglishTeacher = ChildrenEnglishTeacher(yearExperience: 6, yearBirth: 1920); childrenEnglishTeacher.age = 30; print(childrenEnglishTeacher.hasLessonsToday()); print(childrenEnglishTeacher.yearBirth); }
Вывод в консоли

Всё отработало правильно. Наш ChildrenEnglishTeacher переопределил метод hasLessonsToday от вышестоящего класса EnglishTeacher и так же переопределил слегка изменённый сеттор age от базового класса Teacher.
Итак, определение полиморфизма можно дать более понятными словами (после примера).
Принцип полиморфизма в ООП (объектно-ориентированном программировании) предполагает использование одного и того же имени метода или свойства для объектов разных классов. Иными словами, полиморфизм позволяет обращаться к объектам разных классов с помощью одних и тех же методов или свойств.
Зачем нам полиморфизм?
Прежде всего, чтоб убрать дублирование кода, улучшить читаемость и для удобного масштабирования.
