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

Являются ли понятия абстракция и интерфейс равными друг другу?

2.3 Middle🔥 142 комментариев
#Архитектура Flutter#ООП и паттерны

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

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

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

Абстракция и интерфейс: в чём разница

Нет, это не одно и то же. Абстракция и интерфейс — это разные концепции объектно-ориентированного программирования, хотя они часто работают вместе.

Абстракция (Abstraction)

Абстракция — это принцип проектирования, который скрывает сложные детали реализации и выставляет только существенные свойства объекта.

// Абстракция: скрываем сложность работы с БД
abstract class UserRepository {
  // Показываем только существенные операции
  Future<User> findById(String id);
  Future<void> save(User user);
  Future<void> delete(String id);
  
  // Скрываем как именно это реализовано (SQL, Firebase, REST и т.д.)
}

class PostgresUserRepository implements UserRepository {
  // Скрытые детали реализации
  final Database _db;
  final Logger _logger;
  final Cache _cache;
  
  @override
  Future<User> findById(String id) async {
    // Логирование, кеширование, SQL запросы и т.д.
    _logger.info('Finding user $id');
    final cached = await _cache.get(id);
    if (cached != null) return cached;
    
    final user = await _db.query('SELECT * FROM users WHERE id = \$1', [id]);
    await _cache.set(id, user);
    return user;
  }
}

Абстракция позволяет использовать UserRepository, не зная о PostgreSQL, логировании или кеше.

Интерфейс (Interface)

Интерфейс — это контракт, который определяет набор методов, которые должен реализовать класс. Это договор о том, что будет доступно.

// Интерфейс: определяет контракт
abstract class Shape {
  double getArea();
  double getPerimeter();
  void draw();
}

// Классы реализуют интерфейс
class Circle implements Shape {
  final double radius;
  
  Circle(this.radius);
  
  @override
  double getArea() => 3.14 * radius * radius;
  
  @override
  double getPerimeter() => 2 * 3.14 * radius;
  
  @override
  void draw() => print("Drawing circle");
}

class Rectangle implements Shape {
  final double width, height;
  
  Rectangle(this.width, this.height);
  
  @override
  double getArea() => width * height;
  
  @override
  double getPerimeter() => 2 * (width + height);
  
  @override
  void draw() => print("Drawing rectangle");
}

Ключевые различия

1. Назначение

  • Абстракция — скрыть сложность и выставить только нужное
  • Интерфейс — определить контракт для реализации

2. Реализация

  • Абстракция — использует abstract классы, частные поля, methods
  • Интерфейс — определяет методы без реализации

3. Состояние

  • Абстракция — может иметь состояние (поля)
  • Интерфейс — не хранит состояние
// Абстракция с состоянием
abstract class Vehicle {
  String name; // состояние
  int _speed = 0; // приватное состояние
  
  void accelerate() {
    _speed += 10;
    print("$name accelerated to $_speed km/h");
  }
}

// Интерфейс без состояния
abstract class Drawable {
  void draw(); // только метод, без данных
}

Примеры из реальной жизни

Пример 1: HTTP Client

// Интерфейс: определяет контракт
abstract class HttpClient {
  Future<Response> get(String url);
  Future<Response> post(String url, {required String body});
}

// Абстракция: скрывает детали реализации
class DioHttpClient implements HttpClient {
  final Dio _dio;
  final Logger _logger;
  final Interceptor _errorHandler;
  
  DioHttpClient(this._dio, this._logger, this._errorHandler);
  
  @override
  Future<Response> get(String url) async {
    _logger.debug('GET request to $url');
    try {
      return await _dio.get(url);
    } catch (e) {
      _logger.error('Failed to GET $url', e);
      throw _errorHandler.handle(e);
    }
  }
}

Пример 2: Authentication

// Интерфейс: что должно быть реализовано
abstract class AuthProvider {
  Future<User> login(String email, String password);
  Future<void> logout();
  Future<bool> isAuthenticated();
}

// Абстракция: как это на самом деле работает
class FirebaseAuthProvider implements AuthProvider {
  final FirebaseAuth _auth;
  final UserRepository _userRepo;
  final TokenManager _tokenManager;
  
  FirebaseAuthProvider(this._auth, this._userRepo, this._tokenManager);
  
  @override
  Future<User> login(String email, String password) async {
    final credential = await _auth.signInWithEmailAndPassword(
      email: email,
      password: password,
    );
    
    final user = await _userRepo.findById(credential.user!.uid);
    await _tokenManager.saveToken(credential.user!.uid);
    
    return user;
  }
}

Как они работают вместе

// Интерфейс определяет контракт
abstract class Database {
  Future<List<T>> query<T>(String sql);
}

// Абстракция скрывает детали
class SQLiteDatabase implements Database {
  final Database _db; // SQLite драйвер
  final Cache _cache; // Кеш
  final Mutex _mutex; // Синхронизация доступа
  final Logger _logger; // Логирование
  
  @override
  Future<List<T>> query<T>(String sql) async {
    _logger.info('Executing: $sql');
    final cached = await _cache.get(sql);
    if (cached != null) return cached;
    
    await _mutex.acquire();
    try {
      final result = await _db.rawQuery(sql);
      await _cache.set(sql, result);
      return result;
    } finally {
      _mutex.release();
    }
  }
}

// Использование
final db = SQLiteDatabase(...);
await db.query('SELECT * FROM users'); // Не волнует про кеш, логирование, мьютекс

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

Интерфейс:

  • Когда нужно определить контракт для разных реализаций
  • Для полиморфизма и подмены реализаций
  • Для unit тестирования (мокирование)

Абстракция:

  • Когда нужно скрыть сложность
  • Когда есть общее состояние и логика
  • Для инкапсуляции деталей реализации

Вывод

  • Интерфейс — это ЧТО (контракт)
  • Абстракция — это КАК (скрытие деталей)

Интерфейс определяет, какие методы должны быть. Абстракция определяет, как эти методы работают внутри, скрывая сложность от пользователя. Часто они используются вместе для создания чистой архитектуры.

Являются ли понятия абстракция и интерфейс равными друг другу? | PrepBro