Основы наследования
Часть раздела Объектно-ориентированное программирование путешествия по Dart на Coddy — урок 36 из 110.
Наследование позволяет классу приобретать свойства и методы другого класса. Вместо того чтобы переписывать один и тот же код, вы создаете новый класс, который строится на основе существующего. Исходный класс называется родительским (или суперклассом), а новый класс — дочерним (или подклассом).
В Dart вы используете ключевое слово extends для наследования от родительского класса:
class Animal {
String name;
Animal(this.name);
void eat() {
print('$name is eating');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void bark() {
print('$name says woof!');
}
}
void main() {
var dog = Dog('Buddy');
dog.eat(); // Унаследовано от Animal
dog.bark(); // Определено в Dog
}Класс Dog автоматически получает доступ к свойству name и методу eat() из Animal, а также к своему собственному методу bark(). Это создает отношение «is-a» — Dog является Animal.
Дочерний класс может добавлять новые свойства и методы, но он наследует всё публичное от родителя. Обратите внимание, что приватные члены (те, что с _) не доступны напрямую в подклассах из других библиотек, хотя они всё равно существуют в унаследованном объекте.
Задание
ЛегкоДавайте создадим систему транспортных средств, которая демонстрирует, как наследование позволяет дочерним классам повторно использовать и расширять функциональность родительского класса. Вы создадите родительский класс для общих транспортных средств и дочерний класс для конкретного типа транспортного средства.
Вы организуете свой код в два файла:
vehicle.dart: Определите здесь свои классы:- Класс
Vehicle(родительский) со свойствомString brand, конструктором, принимающим бренд, и методомstart(), который выводит[brand] engine starting... - Класс
Motorcycle, который расширяетVehicle. Он должен иметь дополнительное свойствоint cc(объем двигателя), конструктор, принимающий как бренд, так и cc (передающий бренд родителю с помощьюsuper), и собственный методwheelie(), который выводит[brand] is doing a wheelie!
- Класс
main.dart: Импортируйте файл с транспортными средствами и продемонстрируйте наследование в действии:- Создайте
Vehicleс брендом'Toyota' - Вызовите его метод
start() - Создайте
Motorcycleс брендом'Harley'и cc1200 - Вызовите метод мотоцикла
start()(унаследованный от Vehicle) - Вызовите метод мотоцикла
wheelie()(определенный в Motorcycle) - Выведите
Motorcycle engine: [cc]cc, чтобы показать собственное свойство дочернего класса
- Создайте
Обратите внимание, как класс Motorcycle автоматически получает доступ к свойству brand и методу start() из Vehicle, имея при этом собственное уникальное свойство cc и метод wheelie(). В этом и заключается сила наследования — создание нового на основе существующего кода.
Ожидаемый результат:
Toyota engine starting...
Harley engine starting...
Harley is doing a wheelie!
Motorcycle engine: 1200ccШпаргалка
Используйте ключевое слово extends для создания дочернего класса, который наследуется от родительского класса:
class Animal {
String name;
Animal(this.name);
void eat() {
print('$name is eating');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void bark() {
print('$name says woof!');
}
}Дочерний класс наследует все публичные свойства и методы родительского класса. Используйте super в конструкторе дочернего класса для передачи параметров в конструктор родительского класса.
Дочерние классы могут добавлять свои собственные свойства и методы, сохраняя при этом доступ к унаследованным:
var dog = Dog('Buddy');
dog.eat(); // Inherited from Animal
dog.bark(); // Defined in DogЭто создает отношение «является» (is-a) — Dog (собака) является Animal (животным).
Попробуйте сами
import 'vehicle.dart';
void main() {
// TODO: Создайте Vehicle с брендом 'Toyota'
// TODO: Вызовите метод start() объекта vehicle
// TODO: Создайте Motorcycle с брендом 'Harley' и cc 1200
// TODO: Вызовите метод start() объекта motorcycle (унаследованный от Vehicle)
// TODO: Вызовите метод wheelie() объекта motorcycle
// TODO: Выведите 'Motorcycle engine: [cc]cc', используя свойство cc объекта motorcycle
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн Репозиторий