Ответ
В Dart и абстрактные классы, и интерфейсы используются для определения контрактов, но с разной степенью гибкости и реализации.
Абстрактный класс (abstract class)
- Может содержать как абстрактные методы (без тела), так и реализованные методы, поля, конструкторы.
- Поддерживает одиночное наследование (класс может
extendsтолько один абстрактный класс). -
Идеален для создания шаблона с частичной готовой реализацией.
abstract class DataRepository { // Поле с реализацией final String endpoint = '/api/data'; // Абстрактный метод (контракт) Future<List<dynamic>> fetchAll(); // Реализованный метод (общая логика) void logError(String error) { print('Repository error: $error'); } }
class UserRepository extends DataRepository {
@override
Future<List
### Интерфейс
* В Dart **любой класс неявно определяет интерфейс**. Ключевого слова `interface` нет.
* Для реализации интерфейса используется `implements`.
* Класс может реализовать **несколько** интерфейсов.
* При реализации **обязан предоставить свою реализацию ВСЕХ** публичных членов этого класса (и методов, и полей).
```dart
// Классы, которые мы используем как интерфейсы
class JsonSerializable {
String toJson() => ''; // Сигнатура метода
}
class Identifiable {
final int id;
Identifiable(this.id); // Даже поле и конструктор должны быть переопределены
}
// Класс реализует два интерфейса
class User implements JsonSerializable, Identifiable {
@override
int id; // Поле должно быть объявлено
@override
String toJson() => '{"id": $id}'; // Метод должен быть реализован
// Конструктор также нужно объявить
User(this.id);
}
Практическое правило в Dart:
- Используйте
abstract classсextends, когда вам нужна общая базовая логика и отношение "является". - Используйте
implements, когда вам нужна только сигнатура (контракт) или множественное "наследование" поведения.
Ответ 18+ 🔞
А, ну это классика, блядь! Сидишь такой, пишешь на Dart, и тут бац — нужно решить, какую хуйню использовать: абстрактный класс или интерфейс. А разница-то, ёпта, есть, и нехилая.
Представь себе, что абстрактный класс — это как чертеж от старшего инженера, который уже половину работы за тебя сделал, ебать мои старые костыли. Он тебе и контракт накидает (абстрактные методы), и сразу какую-то готовую хуйню впаяет (реализованные методы, поля). Но есть подвох: наследоваться ты можешь только от одного такого папаши. Один, и всё, пиздец. Как в жизни — отца два не бывает.
abstract class DataRepository {
// Вот тебе готовое поле, не еби мозги
final String endpoint = '/api/data';
// А вот это, сынок, тебе самому делать, контракт, блядь
Future<List<dynamic>> fetchAll();
// А это я тебе, ленивая жопа, уже написал, пользуйся
void logError(String error) {
print('Repository error: $error');
}
}
class UserRepository extends DataRepository {
@override
Future<List<dynamic>> fetchAll() {
// Ну вот, только эту херню и реализовать надо
// logError уже есть, овердохуища удобства!
return HttpClient().get(endpoint);
}
}
А теперь смотри сюда, хитрая жопа. Интерфейс в Dart — это вообще пиздопроебибна история. Отдельного слова interface нет, нихуя! Любой класс — он уже неявно интерфейс. И чтобы его реализовать, надо писать implements. И вот тут начинается веселье: ты можешь нацепить на себя интерфейсов, блядь, сколько влезет, как новогоднюю ёлку гирляндами. Но за всё надо платить: ты обязан переписать ВСЁ, что было публичного в том классе. Все методы, все поля — нихуя не унаследуешь, делай сам.
// Смотри, вот два обычных класса. Но для нас они теперь — интерфейсы!
class JsonSerializable {
String toJson() => ''; // Просто сигнатура, нам она важна
}
class Identifiable {
final int id;
Identifiable(this.id); // Ага, и поле, и конструктор — всё часть контракта!
}
// И наш класс хуярит себе два интерфейса сразу
class User implements JsonSerializable, Identifiable {
@override
int id; // Поле id? Объявляй сам, сука!
@override
String toJson() => '{"id": $id}'; // Метод toJson? Пиши с нуля!
// И конструктор тоже свой пиши, нихуя не схалявишь
User(this.id);
}
Так что, чувак, правило простое, как хуй с горы:
- Тянется
extendsкabstract class, когда тебе нужен готовый фундамент и ты говоришь "мой класс является таким-то". Логику частично за тебя напишут. - Хватаешься
implements, когда тебе похуй на реализацию, нужна только форма (контракт), или когда ты хочешь быть одновременно и тем, и этим (множественное "наследование"). Но готовься всё делать сам, доверия ебать ноль.
Выбирай с умом, а то потом сидеть и ебаться с кодом, который не компилится.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶