Ключевое слово super
Часть раздела Объектно-ориентированное программирование путешествия по Dart на Coddy — урок 37 из 110.
Ключевое слово super предоставляет дочернему классу прямой доступ к его родительскому классу. Вы уже видели его в конструкторах с super(name), но оно полезно и в других контекстах.
Когда вам нужно вызвать конструктор родительского класса, super передает аргументы вверх по цепочке наследования:
class Vehicle {
String brand;
int year;
Vehicle(this.brand, this.year);
}
class Car extends Vehicle {
int doors;
Car(String brand, int year, this.doors) : super(brand, year);
}Ключевое слово super также позволяет вам обращаться к методам и свойствам родительского класса из дочернего класса. Это особенно полезно, когда вы хотите использовать поведение родителя наряду со своим собственным:
class Animal {
String name;
Animal(this.name);
void makeSound() {
print('$name makes a sound');
}
}
class Cat extends Animal {
Cat(String name) : super(name);
void makeSound() {
super.makeSound(); // Сначала вызываем метод родителя
print('$name says meow!');
}
}Когда вы вызываете super.makeSound(), вы явно вызываете версию метода родительского класса. Без super, вызов makeSound() будет ссылаться на метод текущего класса, что потенциально может привести к бесконечной рекурсии.
Представьте super как способ сказать «используй версию моего родителя» — будь то конструктор, метод или свойство.
Задание
ЛегкоДавайте создадим систему обмена сообщениями, которая демонстрирует, как ключевое слово super позволяет дочерним классам получать доступ к поведению родительского класса и расширять его. Вы создадите иерархию, в которой различные типы сообщений строятся на основе базового класса сообщений.
Вы организуете свой код в два файла:
message.dart: Определите здесь ваши классы сообщений:- Класс
Message(родительский) со свойствамиString senderиString content. Включите конструктор, который принимает оба значения, и методdisplay(), который выводитFrom [sender]: [content] - Класс
UrgentMessage, который расширяетMessage. Он должен иметь дополнительное свойствоString priority. Конструктор принимает sender, content и priority, передавая первые два родительскому классу с помощьюsuper. Переопределите методdisplay(), чтобы он сначала вызывал родительскую версию с помощьюsuper.display(), а затем выводилPriority: [priority]на следующей строке
- Класс
main.dart: Импортируйте файл сообщений и продемонстрируйте, какsuperработает как в конструкторах, так и в методах:- Создайте обычный
Messageот'Alice'с содержимым'Hello there!' - Вызовите его метод
display() - Выведите пустую строку для разделения
- Создайте
UrgentMessageот'Bob'с содержимым'Server is down!'и приоритетом'HIGH' - Вызовите его метод
display()
- Создайте обычный
Обратите внимание, как UrgentMessage использует super двумя способами: в конструкторе для передачи данных родителю и в переопределенном методе для включения вывода родителя перед добавлением своего собственного.
Ожидаемый результат:
From Alice: Hello there!
From Bob: Server is down!
Priority: HIGHШпаргалка
Ключевое слово super предоставляет доступ к родительскому классу из дочернего класса.
Используйте super() в конструкторе дочернего класса для передачи аргументов в конструктор родителя:
class Vehicle {
String brand;
int year;
Vehicle(this.brand, this.year);
}
class Car extends Vehicle {
int doors;
Car(String brand, int year, this.doors) : super(brand, year);
}Используйте super для вызова родительских методов из переопределенных методов:
class Animal {
String name;
Animal(this.name);
void makeSound() {
print('$name makes a sound');
}
}
class Cat extends Animal {
Cat(String name) : super(name);
void makeSound() {
super.makeSound(); // Сначала вызываем метод родителя
print('$name says meow!');
}
}Без super прямой вызов имени метода относится к версии текущего класса, что может привести к бесконечной рекурсии в переопределенных методах.
Попробуйте сами
import 'message.dart';
void main() {
// TODO: Создайте обычное Message от 'Alice' с содержимым 'Hello there!'
// TODO: Вызовите метод display() для этого сообщения
// TODO: Выведите пустую строку для разделения
// TODO: Создайте UrgentMessage от 'Bob' с содержимым 'Server is down!' и приоритетом 'HIGH'
// TODO: Вызовите метод display() для этого срочного сообщения
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн Репозиторий