Konstruktorlar
Dart-da konstruktor sadəcə "obyekt yaradan funksiya" deyil — dilin ən zəngin hissələrindən biridir və müsahibədə demək olar həmişə soruşulur.
Əsas formalar:
- Default (generative) konstruktor —
Point(this.x, this.y);.this.xqısaltması parametri birbaşa sahəyə yazır, gövdədə əlavə sətir lazım gəlmir. - Named konstruktor —
Point.origin() : x = 0, y = 0;. Dart-da konstruktor overload etmək olmur (eyni adla iki konstruktor yazmaq mümkün deyil), ona görə hər alternativ yaradılma yolu ad alır. - Initializer list —
:işarəsindən sonra, gövdədən əvvəl işləyən hissə. - Redirecting konstruktor —
Point.zero() : this(0, 0);— işi eyni class-ın başqa konstruktoruna ötürür, öz gövdəsi olmur. - Factory konstruktor — mütləq yeni obyekt yaratmır: cache-dən qaytara, alt tip qaytara və ya
null-dan başqa istənilən uyğun instansiya qaytara bilər. - Const konstruktor — obyekti compile-time-da yaradır və eyni dəyərli obyektləri kanonikləşdirir.
Initializer list nə vaxt MƏCBURİDİR? Bu, sualın klassik formasıdır. Üç hal:
finalsahəni hesablanmış dəyərlə doldurmaq lazımdırsa — gövdədəfinal-a yazmaq olmur, çünki gövdə işləyəndə obyekt artıq "tam qurulmuş" sayılır.super(...)konstruktoruna hesablanmış arqument ötürmək lazımdırsa.assert(...)ilə giriş dəyərini obyekt yaranmadan yoxlamaq istəyirsənsə.
İcra sırası (yadda saxlanası siyahı):
1. Initializer list (soldan sağa) — burada this-dən istifadə etmək olmaz
2. Super class-ın konstruktoru
3. Öz gövdən — burada artıq this hazırdır
| Konstruktor növü | Yeni obyekt yaradır? | Tipik istifadə |
|---|---|---|
| Generative — `Order(this.id)` | Bəli, həmişə | Sadə data class-ları, model-lər |
| Named — `Order.draft()` | Bəli | Alternativ yaradılma ssenariləri (overload əvəzi) |
| Redirecting — `Order.empty() : this('')` | Bəli (başqa konstruktor vasitəsilə) | Default dəyərləri bir yerdə saxlamaq |
| Factory — `factory Order.fromJson(...)` | Xeyr — cache, singleton və ya alt tip qaytara bilər | JSON parsing, cache, singleton, tip seçimi |
| Const — `const Point(this.x, this.y)` | Compile-time-da bir dəfə, sonra təkrar istifadə | Dəyişməz (immutable) dəyər obyektləri |
Const konstruktor və kanonikləşdirmə. Konstruktoru const etmək üçün bütün sahələr final olmalı, gövdə boş olmalı və initializer list yalnız compile-time sabitlərindən istifadə etməlidir.
Bundan sonra const Point(1, 2) iki dəfə yazılsa belə, proqramda eyni bir obyekt olacaq (identical(a, b) == true). Buna kanonikləşdirmə deyilir. Diqqət: const konstruktoru olan class-ı const olmadan da çağırmaq olar — o zaman adi runtime obyekti alınır.
Flutter-ə niyə aiddir: widget-lər const konstruktorla yaradılanda framework yenidən qurulma zamanı köhnə və yeni obyektin eyni olduğunu identical ilə dərhal görür və o alt ağacı yenidən qurmur. Yəni const sadəcə stil məsələsi deyil — ölçülə bilən performans qazancıdır. Bu, prefer_const_constructors lint qaydasının mövcud olma səbəbidir.
Müsahibə ipucu. Ən çox verilən sual: "factory konstruktorla adi konstruktorun fərqi nədir?" Zəif cavab: "factory obyekt yaradır". Güclü cavab üç bənddən ibarətdir: (1) generative konstruktor mütləq yeni instansiya yaradır və this-i qaytarır; factory isə qaytarma öhdəliyi daşıyır — nə qaytardığı onun işidir (cache, singleton, alt tip); (2) buna görə factory-nin içində this yoxdur və initializer list yaza bilmir; (3) factory const ola bilməz, ona görə factory-li class-ı const kontekstdə istifadə etmək olmur — Flutter widget-ində bu, real məhdudiyyətdir. Sonra bir konkret nümunə ver: factory Currency(String code) cache-dən qaytarır.
📚 Mənbələr və sənədlər
- Konstruktorlarrəsmidart.dev