Irbisa · Шпаргалка
ООП в Dart
Классы, наследование, интерфейсы, примеси и абстрактные классы
Какие четыре принципа ООП существуют и как каждый из них выглядит в Dart?
Как работают конструкторы в Dart (обычные, именованные и списки инициализации) и почему
final-поля нужно задать до тела конструктора?class Point { final double x; final double y; // generative: fields set straight from parameters Point(this.x, this.y);…Что такое
factory-конструктор, чем он отличается от обычного и может ли он вернутьnullили закешированный экземпляр?class Logger { Logger._internal(this.name); final String name; static final _cache = <String, Logger>{};…Что делает
super.keyв конструкторе виджета и когда super-параметры использовать нельзя?class Avatar extends StatelessWidget { // before: const Avatar({Key? key, required this.url}) : super(key: key); const Avatar({super.key, required this.url, this.size = 40}); final String url; final double size;…Поддерживает ли Dart перегрузку методов и как добиться того же эффекта?
class Toast { // one method instead of show(text), show(text, duration), show(text, duration, action) static void show( String text, { Duration duration = const Duration(seconds: 2), String? actionLabel,…В Dart нет ключевого слова
private. Как работает приватность через_и что означает конструктор._()?// cart.dartclass Cart { Cart._(); // private: other files cannot call it static final instance = Cart._(); final _items = <String>[]; // private to cart.dart…Как работают геттеры и сеттеры в Dart и почему публичное поле можно заменить геттером, не сломав вызывающий код?
class CartItem { CartItem(this.price, this._quantity); final double price; int _quantity; int get quantity => _quantity;…Когда член класса стоит делать
staticи чего статические члены делать не могут?В чём разница между
extends,implementsиwithи какое место здесь занимает абстрактный класс?abstract class Shape { double get area; // abstract: subclasses must provide it String describe() => 'area ${area.toStringAsFixed(1)}'; // inherited} mixin Loggable {…Что такое миксин, когда его выбирают вместо наследования и что делает конструкция
on?mixin Validator { // abstract: the host class must provide it Map<String, String?> get fields; bool get isValid => fields.values.every((v) => v != null && v.isNotEmpty);}…Что такое extension-методы, что они дают по сравнению с функциями-хелперами и когда они не срабатывают?
extension StringCase on String { String capitalize() => isEmpty ? this : '${this[0].toUpperCase()}${substring(1)}';} extension ContextX on BuildContext {…Как работает перегрузка операторов в Dart и какие операторы можно перегрузить?
final class Money { const Money(this.cents); final int cents; Money operator +(Money other) => Money(cents + other.cents); Money operator *(int times) => Money(cents * times);…Этот
Setдолжен был убрать дубликат, но печатает2. Чего не хватает и что будет, если изменить объект, который уже лежит в множестве?class Point { Point(this.x, this.y); int x, y; @override bool operator ==(Object other) => other is Point && other.x == x && other.y == y;} void main() { final points = {Point(1, 2), Point(1, 2)}; print(points.length);}Что такое callable-класс (класс с методом
call()) и когда его стоит писать?abstract interface class UserRepository { Future<String> nameOf(String id);} class GetUserName { GetUserName(this._repo);…Почему виджеты и модели во Flutter неизменяемые и как обеспечить неизменяемость в Dart (
final,@immutable,copyWith)?@immutableclass Profile { Profile({required this.name, this.email, List<String> tags = const []}) : tags = List.unmodifiable(tags); final String name;…Что такое
const-конструктор и почему Flutter предпочитаетconst-виджеты?class Point { const Point(this.x, this.y); // all fields final, no body final int x, y;} void main() {…Что контролируют модификаторы классов Dart 3
base,interface,final,sealedиmixin class?// interface: others implement it, nobody inherits your bodiesabstract interface class UserRepository { Future<String> nameOf(String id);} // base: others may extend, never implement, so _send always runs…Почему Flutter предпочитает композицию наследованию и как бы вы отрефакторили раздутый базовый класс
BaseScreen?// before: class ProfileScreen extends BaseScreen { /* six overridden hooks */ } // after: the shared part is a widget the screens composeclass AsyncView<T> extends StatelessWidget { const AsyncView({super.key, required this.snapshot, required this.builder});…Найдите баг: в интеграционном тесте
ApiClient(baseUrl: server.url)всё равно отправляет запросы в продовый API.class ApiClient { ApiClient._(this.baseUrl); final String baseUrl; static ApiClient? _instance; factory ApiClient({required String baseUrl}) => _instance ??= ApiClient._(baseUrl); Uri endpoint(String path) => Uri.parse('$baseUrl$path');}Что напечатает этот код и почему замена
with Caching, Loggingнаwith Logging, Cachingменяет результат?class Base { String fetch() => 'base';} mixin Caching on Base { @override String fetch() => 'cache(${super.fetch()})';}mixin Logging on Base { @override String fetch() => 'log(${super.fetch()})';} class Repo extends Base with Caching, Logging {} void main() => print(Repo().fetch());Вызов
Screen('home')бросаетLateInitializationError. В каком порядке Dart создаёт объект и как это исправить?class Base { Base() { onInit(); } void onInit() {}} class Screen extends Base { Screen(this.title) : upper = title.toUpperCase() { controller = 'controller for $title'; } final String title, upper; late final String controller; @override void onInit() => print('$title $upper $controller');}Найдите баг:
cart.contains(item)для одного и того же товара возвращает тоtrue, тоfalseв зависимости от того, лежит в корзине обычная версия или версия со скидкой.class Product { Product(this.id); final String id; @override bool operator ==(Object other) => other is Product && other.id == id; @override int get hashCode => id.hashCode;}class SaleProduct extends Product { SaleProduct(super.id, this.discount); final int discount; @override bool operator ==(Object other) => other is SaleProduct && other.id == id && other.discount == discount; @override int get hashCode => Object.hash(id, discount);}