Полиморфизм в языке Dart

от автора

Начнём с определения в википедии:

Полиморфизм в языках программирования и теории типов — способность функции обрабатывать данные разных типов

Существует два вида полиморфизма 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.

Итак, определение полиморфизма можно дать более понятными словами (после примера).

Принцип полиморфизма в ООП (объектно-ориентированном программировании) предполагает использование одного и того же имени метода или свойства для объектов разных классов. Иными словами, полиморфизм позволяет обращаться к объектам разных классов с помощью одних и тех же методов или свойств.

Зачем нам полиморфизм?

Прежде всего, чтоб убрать дублирование кода, улучшить читаемость и для удобного масштабирования.


ссылка на оригинал статьи https://habr.com/ru/articles/786342/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *