Menu
Coddy logo textTech

Основы наследования

Часть раздела Объектно-ориентированное программирование путешествия по 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.

Дочерний класс может добавлять новые свойства и методы, но он наследует всё публичное от родителя. Обратите внимание, что приватные члены (те, что с _) не доступны напрямую в подклассах из других библиотек, хотя они всё равно существуют в унаследованном объекте.

challenge icon

Задание

Легко

Давайте создадим систему транспортных средств, которая демонстрирует, как наследование позволяет дочерним классам повторно использовать и расширять функциональность родительского класса. Вы создадите родительский класс для общих транспортных средств и дочерний класс для конкретного типа транспортного средства.

Вы организуете свой код в два файла:

  • 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' и cc 1200
    • Вызовите метод мотоцикла 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
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование