Что такое ключевое слово implements в Dart?

«Что такое ключевое слово implements в Dart?» — вопрос из категории ООП, который задают на 36% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

implements — это ключевое слово в Dart, которое заставляет класс выполнять контракт (интерфейс) другого класса. В отличие от extends, класс, использующий implements, не наследует реализацию методов и полей. Он обязан предоставить собственную реализацию всех публичных членов (методов, геттеров, сеттеров) имплементируемого класса.

Ключевые особенности:

  • Множественная имплементация: Класс может реализовывать несколько интерфейсов через запятую (implements A, B, C).
  • Строгий контракт: Все методы интерфейса должны быть явно объявлены и реализованы.
  • Полиморфизм: Объект может использоваться через тип своего интерфейса.

Практический пример в Flutter: Создание различных стратегий для сервиса кэширования.

// Определяем интерфейс (контракт) для кэша
abstract class CacheService {
  Future<void> write(String key, String value);
  Future<String?> read(String key);
  Future<void> delete(String key);
}

// Первая реализация: кэш в оперативной памяти
class MemoryCacheService implements CacheService {
  final Map<String, String> _cache = {};

  @override
  Future<void> write(String key, String value) async {
    _cache[key] = value;
  }

  @override
  Future<String?> read(String key) async {
    return _cache[key];
  }

  @override
  Future<void> delete(String key) async {
    _cache.remove(key);
  }
}

// Вторая реализация: кэш с использованием пакета shared_preferences
import 'package:shared_preferences/shared_preferences.dart';

class SharedPrefsCacheService implements CacheService {
  @override
  Future<void> write(String key, String value) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(key, value);
  }

  @override
  Future<String?> read(String key) async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString(key);
  }

  @override
  Future<void> delete(String key) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(key);
  }
}

// Использование в коде
class DataRepository {
  final CacheService cacheService;
  DataRepository(this.cacheService); // Внедряем зависимость через интерфейс

  Future<String> fetchData() async {
    const key = 'my_data';
    final cached = await cacheService.read(key);
    if (cached != null) return cached;
    // ... загрузка с сети
    final newData = 'Данные из сети';
    await cacheService.write(key, newData);
    return newData;
  }
}
// Теперь можно легко подменить реализацию кэша
final repoWithMemoryCache = DataRepository(MemoryCacheService());
final repoWithPrefsCache = DataRepository(SharedPrefsCacheService());

Итог: implements — мощный инструмент для соблюдения контрактов, обеспечения слабой связанности и легкого тестирования (мокинга) в Dart.