← Назад к вопросам

В чем разница между implements и extends?

1.0 Junior🔥 201 комментариев
#Dart#ООП и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между implements и extends в Dart

Это две разные концепции наследования и реализации интерфейсов в Dart. Хотя они похожи на первый взгляд, они решают разные задачи.

extends — Наследование

extends используется для наследования от класса-родителя. Дочерний класс наследует все свойства и методы родительского класса и может переопределить их.

class Animal {
  String name;

  Animal(this.name);

  void makeSound() {
    print('Какой-то звук');
  }

  void sleep() {
    print('$name спит');
  }
}

class Dog extends Animal {
  String breed;

  Dog(String name, this.breed) : super(name);

  @override
  void makeSound() {
    print('Гав-гав!');
  }

  void fetchBall() {
    print('$name принёс мяч');
  }
}

void main() {
  var dog = Dog('Бобик', 'Лабрадор');
  dog.makeSound();  // Гав-гав!
  dog.sleep();      // Бобик спит (наследованный метод)
  dog.fetchBall();  // Бобик принёс мяч
}

Характеристики extends:

  • Наследует все методы и свойства от родителя
  • Может использовать родительские методы через super
  • Иерархия классов (is-a отношение)
  • Может быть только один родительский класс
  • Полиморфизм через переопределение методов

implements — Реализация интерфейса

implements используется для реализации контракта (интерфейса). Класс должен реализовать все методы и свойства интерфейса, но НЕ наследует их реализацию.

abstract class Animal {
  void makeSound();
  void eat();
}

class Dog implements Animal {
  String name;

  Dog(this.name);

  @override
  void makeSound() {
    print('Гав-гав!');
  }

  @override
  void eat() {
    print('$name ест мясо');
  }

  void fetchBall() {
    print('$name принёс мяч');
  }
}

class Bird implements Animal {
  String name;

  Bird(this.name);

  @override
  void makeSound() {
    print('Чирик-чирик!');
  }

  @override
  void eat() {
    print('$name клюёт зёрна');
  }

  void fly() {
    print('$name летает');
  }
}

void main() {
  Animal dog = Dog('Бобик');
  Animal bird = Bird('Чик');

  dog.makeSound();  // Гав-гав!
  bird.makeSound(); // Чирик-чирик!
  dog.eat();        // Бобик ест мясо
  bird.eat();       // Чик клюёт зёрна
}

Характеристики implements:

  • Класс обязан реализовать все методы интерфейса
  • НЕ наследует реализацию, только сигнатуру
  • Можно реализовать несколько интерфейсов одновременно
  • Определяет контракт (что должно быть, но не как)
  • Позволяет полиморфизм без иерархии

Сравнительная таблица

Аспектextendsimplements
ТипНаследованиеРеализация интерфейса
Наследует реализациюДаНет
Наследует сигнатуруДаДа
КоличествоОдин классНесколько интерфейсов
ИерархияЕсть (is-a)Нет
super доступенДаНет
ИспользованиеПереиспользование кодаОпределение контракта

Практический пример

// Интерфейс — контракт
abstract class PaymentProcessor {
  void processPayment(double amount);
  bool refund(double amount);
}

// Базовый класс с реализацией
class BasePaymentProcessor {
  void logTransaction(String message) {
    print('[LOG] $message');
  }
}

// Класс, который и наследует, и реализует
class CreditCardProcessor extends BasePaymentProcessor implements PaymentProcessor {
  String cardNumber;

  CreditCardProcessor(this.cardNumber);

  @override
  void processPayment(double amount) {
    logTransaction('Обработка платежа $amount на карту $cardNumber');
    print('Платёж принят!');
  }

  @override
  bool refund(double amount) {
    logTransaction('Возврат $amount на карту $cardNumber');
    return true;
  }
}

class PayPalProcessor implements PaymentProcessor {
  String email;

  PayPalProcessor(this.email);

  @override
  void processPayment(double amount) {
    print('Отправка платежа $amount на $email через PayPal');
  }

  @override
  bool refund(double amount) {
    print('Возврат через PayPal');
    return true;
  }
}

void main() {
  PaymentProcessor creditCard = CreditCardProcessor('1234-5678-9012-3456');
  PaymentProcessor paypal = PayPalProcessor('user@example.com');

  creditCard.processPayment(100);  // Полиморфизм
  paypal.processPayment(50);
}

Когда использовать extends

✅ Есть общая реализация кода ✅ is-a отношение (Собака IS-A Животное) ✅ Переиспользование кода ✅ Иерархия классов

Когда использовать implements

✅ Определение контракта ✅ Разные способы реализации одного интерфейса ✅ Несколько источников функциональности ✅ Loose coupling между классами

Множественная реализация

Важное отличие Dart: в Dart можно реализовать несколько интерфейсов (implements), но наследовать можно только от одного класса (extends).

class Dog extends Animal implements Comparable, Runnable {
  // Наследует от Animal
  // Реализует интерфейсы Comparable и Runnable
}

Заключение

extends используется когда нужно переиспользовать код и создать иерархию классов. implements используется когда нужно определить контракт, который разные классы могут реализовать по-своему. На практике часто используют оба: наследование для переиспользования кода и интерфейсы для определения контрактов.