企業(yè)網(wǎng)站模板庫單位網(wǎng)站和新媒體建設(shè)制度
鶴壁市浩天電氣有限公司
2026/01/24 08:53:36
企業(yè)網(wǎng)站模板庫,單位網(wǎng)站和新媒體建設(shè)制度,網(wǎng)絡(luò)推廣專員是干什么的,做美食網(wǎng)站視頻序言
在dart中#xff0c;允許多種形式的構(gòu)造方法#xff0c;上篇類中#xff0c;也有涉略。在這篇文章中我們進(jìn)行深入的學(xué)習(xí)。
構(gòu)造 方法的類型
Generative constructors、Default constructors、Named constructors、Constant constructors、Redirecting constructors、Fa…序言在dart中允許多種形式的構(gòu)造方法上篇類中也有涉略。在這篇文章中我們進(jìn)行深入的學(xué)習(xí)。構(gòu)造 方法的類型Generative constructors、Default constructors、Named constructors、Constant constructors、Redirecting constructors、Factory constructors、Redirecting factory constructors以及Constructor tear-offs這些都是官方文檔中給到的構(gòu)造方法的類型下面我們逐一了解Generative constructors是一種類似java的構(gòu)造函數(shù)基礎(chǔ)的classPoint{// Instance variables to hold the coordinates of the point.double x;double y;// Generative constructor with initializing formal parameters:Point(this.x,this.y);}Default constructors默認(rèn)構(gòu)造當(dāng)你沒有明確聲明構(gòu)造方法時就會使用這個Named constructors命名構(gòu)造當(dāng)你給構(gòu)造函數(shù)起了一個其他名字時就是命名構(gòu)造但命名必須遵循class.name的形式如下constdouble xOrigin0;constdouble yOrigin0;classPoint{finaldouble x;finaldouble y;// Sets the x and y instance variables// before the constructor body runs.Point(this.x,this.y);// Named constructorPoint.origin():xxOrigin,yyOrigin;}子類不會繼承父類的命名構(gòu)造Constant constructors如果類生成不變的對象將這些對象設(shè)置為編譯時常量。要使對象成為編譯時常量定義一個const構(gòu)造函數(shù)并將所有實例變量設(shè)置為final。classImmutablePoint{staticconstImmutablePoint originImmutablePoint(0,0);finaldouble x,y;constImmutablePoint(this.x,this.y);}常量構(gòu)造函數(shù)并不總是創(chuàng)建常量。它們可以在非常量上下文中調(diào)用。如下voidmain(){constImmutablePoint pImmutablePoint(10,20);varp1constImmutablePoint(10,20);varp2ImmutablePoint(10,20);//這個叫非常量上下文print(pp1);//trueprint(pp2);//falseprint(p1p2);//false}classImmutablePoint{staticconstImmutablePoint originImmutablePoint(0,0);finaldouble x,y;constImmutablePoint(this.x,this.y);}Redirecting constructors構(gòu)造函數(shù)可以重定向到同一個類中的另一個構(gòu)造函數(shù)。重定向構(gòu)造函數(shù)有一個空主體。構(gòu)造函數(shù)使用this代替冒號:后面的類名。classPoint{double x,y;// The main constructor for this class.Point(this.x,this.y);// Delegates to the main constructor.Point.alongXAxis(double x):this(x,0);}Factory constructors這個上篇文章也講到了當(dāng)遇到下列兩種實現(xiàn)構(gòu)造函數(shù)的情況之一時請使用factory關(guān)鍵字構(gòu)造函數(shù)并不總是創(chuàng)建類的新實例。盡管工廠構(gòu)造函數(shù)不能返回null但它可能返回從緩存中創(chuàng)建一個現(xiàn)有實例而不是創(chuàng)建一個新的實例 子類型的新實例在構(gòu)建實例之前你需要執(zhí)行一些重要的工作。這可能包括檢查參數(shù)或進(jìn)行任何在初始化列表中無法處理的其他處理。varloggerLogger(UI);logger.log(Button clicked);varlogMap{name:UI};varloggerJsonLogger.fromJson(logMap);classLogger{finalString name;bool mutefalse;// _cache is library-private, thanks to// the _ in front of its name.staticfinalMapString,Logger_cacheString,Logger{};factoryLogger(String name){return_cache.putIfAbsent(name,()Logger._internal(name));}factoryLogger.fromJson(MapString,Objectjson){returnLogger(json[name].toString());}Logger._internal(this.name);voidlog(String msg){if(!mute)print(msg);}}工廠構(gòu)造不能訪問thisRedirecting factory constructors有了上面的經(jīng)驗這個也不難理解了factoryListenable.merge(ListListenablelistenables)_MergingListenable普通的工廠構(gòu)造函數(shù)似乎可以創(chuàng)建和返回其他類的實例。這將使重定向工廠變得不必要。重定向工廠有幾個優(yōu)點抽象類可能會提供一個使用另一個類的常量構(gòu)造函數(shù)的常量構(gòu)造函數(shù)。重定向工廠構(gòu)造函數(shù)避免了轉(zhuǎn)發(fā)器重復(fù)形式參數(shù)及其默認(rèn)值的需要。Constructor tear-offs支持撕開看下面的例子finalListintcharCodes[72,101,108,108,111,33];// Hello!// Use a tear-off for a named constructor:varstringscharCodes.map(String.fromCharCode);// Use a tear-off for an unnamed constructor:varbufferscharCodes.map(StringBuffer.new);上面的代碼中使用了lamada去除后如下// Instead of a lambda for a named constructor:varstringscharCodes.map((code)String.fromCharCode(code));// Instead of a lambda for an unnamed constructor:varbufferscharCodes.map((code)StringBuffer(code));Instance variable initialization 實例變量初始化dart中有3種變量初始化方式Initialize instance variables in the declaration聲明時初始化classPointA{double x1.0;double y2.0;// The implicit default constructor sets these variables to (1.0,2.0)// PointA();overrideStringtoString(){returnPointA($x,$y);}}Use initializing formal parameters使用初始化形式參數(shù)初始化參數(shù)也可以是可選的classPointB{finaldouble x;finaldouble y;// Sets the x and y instance variables// before the constructor body runs.PointB(this.x,this.y);// 初始化參數(shù)也可以是可選參數(shù)PointB.optional([this.x0.0,this.y0.0]);}私有字段不能用作命名初始化形式變量??梢允褂孟旅娴姆绞絚lassPointB{// ...PointB.namedPrivate({required double x,required double y}):_xx,_yy;// ...}上面的寫法也適用于命名變量classPointC{double x;// must be set in constructordouble y;// must be set in constructor// Generative constructor with initializing formal parameters// with default valuesPointC.named({this.x1.0,this.y1.0});overrideStringtoString(){returnPointC.named($x,$y);}}// Constructor using named variables.finalpointCPointC.named(x:2.0,y:2.0);所有通過初始化形式參數(shù)引入的變量都是final變量并且只在初始化變量的作用域內(nèi)。要執(zhí)行無法在初始化列表中表達(dá)的邏輯請使用該邏輯創(chuàng)建工廠構(gòu)造函數(shù)或靜態(tài)方法。然后您可以將計算值傳遞給普通構(gòu)造函數(shù)。構(gòu)造函數(shù)的參數(shù)可以聲明為可空類型并且可以被初始化或不被初始化classPointD{double?x;// null if not set in constructordouble?y;// null if not set in constructor// Generative constructor with initializing formal parametersPointD(this.x,this.y);overrideStringtoString(){returnPointD($x,$y);}}Use an initializer list使用初始化列表在運(yùn)行構(gòu)造函數(shù)體之前可以初始化實例變量。用逗號分隔初始化方法。// Initializer list sets instance variables before// the constructor body runs.Point.fromJson(MapString,doublejson):xjson[x]!,yjson[y]!{print(In Point.fromJson(): ($x, $y));}初始化列表的右側(cè)不能訪問this在開發(fā)期間可以通過初始話列表使用assert驗證輸入?yún)?shù)Point.withAssert(this.x,this.y):assert(x0){print(In Point.withAssert(): ($x, $y));}初始化列表也可以用來設(shè)置final值如下classA{finalint x;// A(this.x);A(int u):xu;}Constructor inheritance構(gòu)造函數(shù)的繼承子類不會從超類或直接父類繼承構(gòu)造方法。如果類沒有聲明構(gòu)造方法那么只能使用默認(rèn)的構(gòu)造方法。類可以繼承超類的參數(shù)。這些稱為超參數(shù)super parameter構(gòu)造函數(shù)的工作方式與調(diào)用靜態(tài)方法鏈的方式有些類似。每個子類都可以調(diào)用超類的構(gòu)造函數(shù)來初始化實例就像子類調(diào)用超類的靜態(tài)方法一樣。這個過程不會“繼承”構(gòu)造函數(shù)體或簽名。Non-default superclass constructors非默認(rèn)超類構(gòu)造Dart按以下順序執(zhí)行構(gòu)造函數(shù)初始化器列表超類的未命名、無參數(shù)的構(gòu)造函數(shù)主類的無參數(shù)構(gòu)造函數(shù)如果超類沒有未命名的、無參數(shù)的構(gòu)造方法就調(diào)用超類中的一個構(gòu)造方法。在構(gòu)造函數(shù)主體之前如果有的話在冒號:之后指定超類的構(gòu)造函數(shù)。classPerson{String?firstName;Person.fromJson(Map data){print(in Person);}}classEmployeeextendsPerson{// Person does not have a default constructor;// you must call super.fromJson().Employee.fromJson(Map data):super.fromJson(data){print(in Employee);}}由于Dart在調(diào)用構(gòu)造函數(shù)之前計算超類構(gòu)造函數(shù)的參數(shù)因此參數(shù)可以是類似于函數(shù)調(diào)用的表達(dá)式classEmployeeextendsPerson{Employee():super.fromJson(fetchDefaultData());// ···}超類構(gòu)造函數(shù)的參數(shù)無法訪問this。例如參數(shù)可以調(diào)用靜態(tài)方法但不能調(diào)用實例方法Super parameters為了避免將每個參數(shù)都傳入構(gòu)造函數(shù)的父類調(diào)用中可以使用 super-initializer 參數(shù)超類初始化參數(shù)將參數(shù)直接轉(zhuǎn)發(fā)到指定或默認(rèn)的父類構(gòu)造函數(shù)。此功能不能與重定向構(gòu)造函數(shù)一起使用。classDogextendsAnimal{finalString breed;// 傳統(tǒng)方式需要將 name 手動傳遞給 superDog(String name,this.breed):super(name);}classDogextendsAnimal{finalString breed;// 新方式使用 super-initializer 參數(shù)Dog(super.name,this.breed);// ↑ super.name 自動將 name 參數(shù)轉(zhuǎn)發(fā)給父類 Animal 構(gòu)造函數(shù)}下面是個錯誤案例Vector3d.xAxisError(super.x):z0,super(0);// BAD這個命名構(gòu)造函數(shù)試圖設(shè)置x的值兩次一次是在super構(gòu)造函數(shù)中另一次是作為位置超參數(shù)。因為它們都指向位置參數(shù)x所以會導(dǎo)致錯誤。當(dāng)超類構(gòu)造函數(shù)有命名參數(shù)時你可以將它們分配到命名的 super 參數(shù)如下例中的 super.y超類構(gòu)造函數(shù)調(diào)用中的命名參數(shù)如 super.named(x: 0)classVector2d{// ...Vector2d.named({requiredthis.x,requiredthis.y});}classVector3dextendsVector2d{finaldouble z;// Forward the y parameter to the named super constructor like:// Vector3d.yzPlane({required double y, required this.z})// : super.named(x: 0, y: y);Vector3d.yzPlane({requiredsuper.y,requiredthis.z}):super.named(x:0);}小結(jié)太靈活了