Mavzu: Konstruktorlat va ularni tashkil etish usullari
Konstruktorlar klass nomi bilan bir xil bo’lgan funksiya yaratish orqali kiritiladi. Eng keng tarqalgan konstruktorlardan biri bu — generativ konstruktor bo’lib, klassning yangi obyektini hosil qiladi:
class Point {
double x = 0;
double y = 0; Point(double x, double y) {
// Buni qilishning yaxshiroq usuli ham bor, kuzatishda davom eting.
this.x = x;
this.y = y;
}
}
this kalitso’zi joriy obyektni bildiradi. Eslatma:this kalitso’zini nomlar bilan “kelishmovchilik” (ya’ni o’zgaruvchiga va konstruktor argumentiga bir xil nom berilganda) bo’lgandagina ishlating, chunki Dart bundan ko’p ham foydalanmaydi.
O’zgaruvchiga konstruktor argumentini o’zlashtirishning bir necha qoliplari keng tarqalgan bo’lsada, Dart bu yo’llardan eng “qaymog’i” bo’lgan “syntactic sugar” usulini taklif qiladi:
class Point {
double x = 0;
double y = 0; // konstruktor "tanasi" ishga tushmasdan oldin
// x va y ni kiritish uchun Syntactic sugar
Point(this.x, this.y);
}
Default konstruktorlar
Agar Siz konstruktor kiritmasangiz, default konstruktor Siz uchun tayyor holatda turgan bo’ladi. Default konstruktorda argument bo’lmaydi va superklassdagi argumentsiz konstruktorni chaqiradi.
Konstruktorlar meros qilib olinmaydi
Subklasslar o’zlarining superklasslaridan konstruktorlarni meros qilib olishmaydi. Konstruktor kiritmaydigan subklassda faqatgina default (argumentsiz, nomsiz) konstruktor mavjud bo’ladi.
Nomlangan konstruktorlar
Klassda bir nechta konstruktorlarni ishlata olish, qo’shimcha aniqlik kiritish uchun yoki asosiy klassdagi ba’zi bir funksiyalardan foydalanishning hojati bo’lmagan vaqtda nomlangan konstruktorlardan foydalanish ayni muddao:
const double xOrigin = 0;
const double yOrigin = 0;class Point {
double x = 0;
double y = 0; Point(this.x, this.y); // Nomlangan konstruktor
Point.origin()
: x = xOrigin,
y = yOrigin;
}
Eslab qolishingiz muhim bo’lgan jihat shuki, konstruktorlar meros qilib olinmaydi. Bu degani superklassning nomlangan konstruktori subklassdan meros qilib olinmagan. Agar Siz superklassda belgilangan nomlangan konstruktorli subklass yaratmoqchi bo’lsangiz, o’sha konstruktorni subklassda ishlatishingiz kerak bo’ladi.
Quyidagi misolda Employee klassi uchun yaratilgan konstruktor Person deb nomlangan superklassdagi nomlangan konstruktorni chaqiradi.
Eslab qolishingiz muhim bo’lgan jihat shuki, konstruktorlar meros qilib olinmaydi. Bu degani superklassning nomlangan konstruktori subklassdan meros qilib olinmagan. Agar Siz superklassda belgilangan nomlangan konstruktorli subklass yaratmoqchi bo’lsangiz, o’sha konstruktorni subklassda ishlatishingiz kerak bo’ladi.
Quyidagi misolda Employee klassi uchun yaratilgan konstruktor Person deb nomlangan superklassdagi nomlangan konstruktorni chaqiradi.
Superklass construktori argumentlari konstruktor chaqirilmasidan avval ishga tushgani sababli, argument funksiyaniChaqir singari ifoda bo’lishi ham mumkin:
class Employee extends Person { Employee() : super.fromJson(fetchDefaultData()); // ··· }
Ogohlantirish: Superklass argumentlarida this ga kirishga huquq yo’q. Masalan, argumentlar statik metodlarni chaqira oladi, lekin metodlarni emas.
Factory konstruktorlari
Agar Siz o’z klassidan har doim ham obyekt olmaydigan konstruktor yaratmoqchi bo’lsangiz factory kalitso’zini konstruktoringiz oldidan qo’shib ketishingiz kerak bo’ladi. Masalan, factory konstruktor keshdan yoki o’zining subtype’idan obyekt qaytarishi mumkin. Factory konstruktorlari uchun yana bir holat — bu boshlang’ich ro’yhatida ko’rib bo’lmaydigan logic (kalitso’z) yordamida yakuniy o’zgaruvchini ishga tushirish.
Quyidagi misolda, Logger factory konstruktori keshdan obyekt qaytaradi va Logger.fromJson factory konstruktori JSON obyektidan o’zgaruvchi yaratadi.
class Logger {
final String name;
bool mute = false; // _cache - maxfiy o'zgaruvchi,
// o'zgaruvchidan oldinda turgan "_" uni maxfiy qiladi.
static final Map _cache =
{}; factory Logger(String name) {
return _cache.putIfAbsent(
name, () => Logger._internal(name));
} factory Logger.fromJson(Map json) {
return Logger(json['name'].toString());
} Logger._internal(this.name); void log(String msg) {
if (!mute) print(msg);
}
}
Eslatma: Factory konstruktorlaridathis ga kirishga huquq yo’q.
Boshqa konstruktorlarni qanday chaqirsangiz, factory konstruktorlarni ham shunday chaqirasiz:
var logger = Logger('UI');
logger.log('Button clicked');var logMap = {'name': 'UI'};
var loggerJson = Logger.fromJson(logMap);