Переопределение методов
Часть раздела Объектно-ориентированное программирование путешествия по Dart на Coddy. Урок 38 из 110.
Переопределение method происходит, когда дочерний class предоставляет собственную реализацию method, который уже существует в parent class. Это позволяет подклассам настраивать унаследованное поведение, сохраняя ту же сигнатуру method.
Когда вы определяете метод в дочернем классе с тем же именем и параметрами, что и метод в родительском классе, версия дочернего класса берет верх:
class Animal {
String name;
Animal(this.name);
void speak() {
print('$name makes a sound');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void speak() {
print('$name barks: Woof!');
}
}
void main() {
var animal = Animal('Generic');
var dog = Dog('Buddy');
animal.speak(); // Generic издаёт звук
dog.speak(); // Buddy лает: Woof!
}Когда вы вызываете speak() для экземпляра Dog, Dart выполняет версию Dog, а не Animal. Дочерний класс переопределил метод parent.
Вы можете also объединить переопределение с super, чтобы расширить, а не заменить поведение parent:
class Cat extends Animal {
Cat(String name) : super(name);
void speak() {
super.speak(); // Сначала вызвать версию родителя
print('$name also purrs');
}
}Этот шаблон позволяет создавать новые возможности на основе существующих. Ключевое правило простое: тот же метод и параметры в дочернем классе заменяют реализацию родительского класса при вызове для экземпляров дочернего класса.
Задание
ЛегкоДавайте создадим систему уведомлений, которая демонстрирует, как дочерние class могут переопределять методы parent для настройки поведения. Вы создадите разные типы уведомлений, каждый из которых доставляет сообщения своим уникальным способом.
Вы организуете код в двух файлах:
notification.dart: здесь Define иерархию уведомлений:- class
Notification(parent) с полямиString titleиString message. Добавьте constructor, принимающий оба значения, и methodsend(), который выводитNotification: [title] - [message] - class
EmailNotification, который extendsNotificationи добавляет свойствоString recipient. Переопределите methodsend(), чтобы он выводилSending email to [recipient]: [title] - [message] - class
PushNotification, который extendsNotificationи добавляет свойствоString deviceId. Переопределите methodsend(), чтобы сначала вызватьsend()parent с помощьюsuper, а затем вывестиPushed to device: [deviceId]на следующей строке
- class
main.dart: импортируйте файл с уведомлениями и продемонстрируйте переопределение method в действии:- Create базовый
Notificationс заголовком'Alert'и сообщением'System update available' - Call его method
send() - Выведите пустую строку
- Create
EmailNotificationс заголовком'Welcome', сообщением'Thanks for signing up!'и recipient'user@example.com' - Call его method
send() - Выведите пустую строку
- Create
PushNotificationс заголовком'Reminder', сообщением'Meeting in 10 minutes'и deviceId'DEVICE-001' - Call его method
send()
- Create базовый
Обратите внимание, как EmailNotification полностью заменяет поведение parent, тогда как PushNotification расширяет его, сначала вызывая super.send(). Оба подхода являются допустимыми способами переопределения методов в зависимости от ваших потребностей.
Ожидаемый результат:
Notification: Alert - System update available
Sending email to user@example.com: Welcome - Thanks for signing up!
Notification: Reminder - Meeting in 10 minutes
Pushed to device: DEVICE-001Попробуйте сами
import 'notification.dart';
void main() {
// TODO: Create a base Notification with title 'Alert' and message 'System update available'
// Вызовите его метод send()
// TODO: Выведите пустую строку
// TODO: Создайте EmailNotification с:
// - title: 'Welcome'
// - message: 'Thanks for signing up!'
// - recipient: 'user@example.com'
// Вызовите его метод send()
// TODO: Выведите пустую строку
// TODO: Создайте PushNotification с:
// - title: 'Reminder'
// - message: 'Meeting in 10 minutes'
// - deviceId: 'DEVICE-001'
// Вызовите его метод send()
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыБиблиотеки и импортВведение в ООПКлассы и объектыКлючевое слово thisМетодыПеременные экземпляраОсновы конструкторовИтоги — Простой калькулятор4Null-безопасность
Введение в Null-безопасностьNullable и Non-Nullable типыОператоры ? и !Ключевое слово Late и Null-безопасностьNull-aware операторыNull-безопасность в классахИтоги — Система профилей пользователей7Абстрактные классы и интерфейсы
Абстрактные классыАбстрактные методыИнтерфейсы в DartНеявные интерфейсыРеализация против наследованияМножественные интерфейсыИтоги — Калькулятор фигур10Коллекции и обобщения
Обзор List, Set, MapТипобезопасные коллекцииОбобщенные классыОбобщенные методыОграничения обобщенийIterable и IteratorИтоги: Обобщенное хранилище13Продвинутые концепции ООП
Композиция против наследованияМетоды расширенияВызываемые классыЗапечатанные классы (Dart 3)Записи (Dart 3)Паттерны и сопоставление (3.0)Перечисления с методами16Проект: Управление библиотекой
Обзор проектаКлассы Book и User2Конструкторы в Dart
Конструктор по умолчаниюИменованные конструкторыСписки инициализацииКонстантные конструкторыФабричные конструкторыПеренаправляющие конструкторыИтоги — Shape Builder5Инкапсуляция
Публичные и приватные членыСоглашение о префиксе _Приватность на уровне библиотекГеттеры и сеттеры: подробный разборСкрытие данныхИтоги — Записи о студентах8Mixins
Введение в MixinsСоздание MixinsИспользование нескольких MixinsКлючевое слово on в MixinsMixin и наследованиеMixin и интерфейсИтоги: Система животных11Специальные методы
Переопределение toString()Переопределение hashCode и ==Интерфейс ComparableМетод call()Переопределение noSuchMethodПовторение — Пользовательская коллекция14Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy3Свойства классов
Члены экземпляра и статические членыПоля Final и ConstПеременные LateСтатические методы и поляГеттеры и сеттерыИтоги — Менеджер банковского счета6Наследование
Основы наследованияКлючевое слово superПереопределение методовАннотация @overrideКлючевое слово final для классовКонструкторы и наследованиеИтоги: Иерархия сотрудников9Полиморфизм
Основы полиморфизмаПолиморфизм через интерфейсыПроверка типов во время выполненияОператоры is и asКлючевое слово covariantИтоги — Обработчик платежей12Асинхронное ООП
Futures и async/awaitОсновы StreamsКонтроллеры StreamАсинхронные конструкторыАсинхронность в методах классовИтоги — Data Fetcher15Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн РепозиторийПотренируйтесь самостоятельно: Онлайн-компилятор Dart