類
- Dart 是一種面向?qū)ο蟮恼Z(yǔ)言岭皂,具有類和基于 mixin 的繼承郊霎,每個(gè)對(duì)象都是一個(gè)類的實(shí)例,所有類都來(lái)自
Object
類爷绘;
- Dart 使用
class
關(guān)鍵字表示一個(gè)類书劝,對(duì)象具有由函數(shù)和數(shù)據(jù)(分別為方法和實(shí)例變量)組成的成員,我們通過(guò) new 關(guān)鍵字來(lái)創(chuàng)建一個(gè)實(shí)例對(duì)象土至;
- Dart關(guān)于class類的定義购对,與
Java
完全類似;
void main(List<String> args) {
Person person = new Person("yanzi", 33);
person.run();
person.eat();
}
class Person {
//屬性成員
String name;
int age;
//構(gòu)造方法
Person(String name, int age) {
this.name = name;
this.age = age;
}
//實(shí)例方法
void run() {
print("run");
}
void eat() {
print("eat");
}
}
- 構(gòu)造函數(shù):類的構(gòu)造函數(shù)陶因,是用來(lái)創(chuàng)建實(shí)例對(duì)象的函數(shù)骡苞;
默認(rèn)構(gòu)造函數(shù)
- 當(dāng)class沒(méi)有自定義構(gòu)造函數(shù)時(shí),系統(tǒng)會(huì)默認(rèn)生成無(wú)參的構(gòu)造函數(shù)楷扬;
void main(List<String> args) {
//無(wú)參構(gòu)造函數(shù)
Person person = new Person();
person.run();
person.eat();
}
class Person {
//屬性成員
String name;
int age;
//實(shí)例方法
void run() {
print("run");
}
void eat() {
print("eat");
}
}
自定義構(gòu)造函數(shù)
- 如果class自定義了構(gòu)造函數(shù)解幽,那么默認(rèn)構(gòu)造函數(shù)為Person()就會(huì)被覆蓋,不能使用了烘苹;
void main(List<String> args) {
Person person = new Person("yanzi", 33);
person.run();
person.eat();
}
class Person {
//屬性成員
String name;
int age;
//自定義構(gòu)造函數(shù)
Person(String name, int age) {
this.name = name;
this.age = age;
}
//實(shí)例方法
void run() {
print("run");
}
void eat() {
print("eat");
}
}
- 上述自定義構(gòu)造函數(shù)躲株,可采用語(yǔ)法糖的簡(jiǎn)潔寫法,如下所示:
void main(List<String> args) {
Person person = new Person("yanzi", 33);
person.run();
person.eat();
}
class Person {
//屬性成員
String name;
int age;
//自定義構(gòu)造函數(shù) -- 語(yǔ)法糖
Person(this.name, this.age);
//實(shí)例方法
void run() {
print("run");
}
void eat() {
print("eat");
}
}
命名構(gòu)造函數(shù)
- 為構(gòu)造函數(shù)镣衡,定義一個(gè)指定的名稱霜定;
void main(List<String> args) {
Person person = Person.withNameAndAge("yanzi", 32);
person.run();
person.eat();
Person person1 = Person.fromMap({"name": "li", "age": 30});
person1.run();
person1.eat();
}
class Person {
//屬性成員
String name;
int age;
//命名構(gòu)造函數(shù)
Person.withNameAndAge(this.name, this.age);
Person.fromMap(Map<String, dynamic> map) {
this.name = map["name"];
this.age = map["age"];
}
//實(shí)例方法
void run() {
print("run");
}
void eat() {
print("eat");
}
}
-
withNameAndAge
與fromMap
,都是Person類的命名構(gòu)造函數(shù)廊鸥,有自己獨(dú)有的函數(shù)名稱望浩;
構(gòu)造函數(shù)包含可選參數(shù)
- 在構(gòu)造函數(shù)中,支持可選參數(shù)惰说,在調(diào)用構(gòu)造函數(shù)時(shí)磨德,對(duì)于可選參數(shù),可傳或者不傳助被;
void main(List<String> args) {
Person person1 = Person("yanzi");
Person person2 = Person("sss", age: 22);
Person person3 = Person.init("aaa");
Person person4 = Person.init("cccc", age: 26);
}
class Person {
String name;
int age;
//其中age為可選參數(shù)
Person(String name, {int age}) {
this.name = name;
this.age = age;
}
//其中age為可選參數(shù)
Person.init(this.name, {this.age});
}
初始化列表
- 與C++的語(yǔ)法類似剖张;
- 初始化列表的使用
只能在構(gòu)造函數(shù)中
切诀;
- 在構(gòu)造函數(shù)的小括號(hào)后面揩环,使用
冒號(hào):
連接初始化的列表;
main(List<String> args) {
var p = Person("SF");
print(p.age);
}
class Person {
//被final修飾的變量為常量 只能被賦值一次
final String name;
final int age;
//初始化列表與C++語(yǔ)法類似
//創(chuàng)建對(duì)象時(shí)幅虑,若傳入age,那么就使用傳入的age,如果沒(méi)有傳入age,那么使用默認(rèn)值10丰滑,age為可選參數(shù)
Person(this.name, {int age}) : this.age = age ?? 10 {
//在執(zhí)行此大括號(hào)的代碼時(shí),對(duì)象已經(jīng)初始化完畢了
//必須保證在執(zhí)行此大括號(hào)的代碼之前,final修飾的name與age必須已經(jīng)初始化
//所以下面代碼報(bào)錯(cuò)
//this.age = 10;
}
//存在局限性
//Person(this.name, {this.age = 10});
}
-
Person(this.name, {int age}) : this.age = age ?? 10
:初始化列表褒墨,在執(zhí)行大括號(hào)中的代碼之前炫刷,完成對(duì)象的初始化;
- 可以在構(gòu)造的時(shí)候初始化一些參數(shù)值郁妈,對(duì)于一些
final修飾的屬性
初始化以后固定值不會(huì)在變浑玛,使用初始化列表,就非常合適噩咪;
重定向構(gòu)造函數(shù)
-
在一個(gè)構(gòu)造函數(shù)中顾彰,去調(diào)用另一個(gè)構(gòu)造函數(shù)
,注意??是在冒號(hào)
后面使用this進(jìn)行調(diào)用
胃碾;
main(List<String> args) {
var p = Person("SF");
print(p.age); //22
}
class Person {
String name;
int age;
//調(diào)用自定義構(gòu)造函數(shù)Person._internal
Person(String name) : this._internal(name, 22);
Person._internal(this.name, this.age);
}
常量構(gòu)造函數(shù)
- 在某些情況下涨享,
傳入相同值時(shí)
,我們希望返回同一個(gè)對(duì)象
仆百,這個(gè)時(shí)候厕隧,可以使用常量構(gòu)造方法;
- 默認(rèn)情況下俄周,創(chuàng)建對(duì)象時(shí)吁讨,即使傳入相同的參數(shù),創(chuàng)建出來(lái)的也不是同一個(gè)對(duì)象峦朗,但是若在構(gòu)造函數(shù)前加上
const
進(jìn)行修飾挡爵,那么可以保證同一個(gè)參數(shù),創(chuàng)建出來(lái)的對(duì)象是相同的甚垦,這樣的構(gòu)造函數(shù)稱之為常量構(gòu)造函數(shù)
茶鹃;
main(List<String> args) {
const p1 = Person("liyanyan");
const p2 = Person("liyanyan");
//p1與p2是同一個(gè)對(duì)象
print(identical(p1, p2));
}
class Person {
final String name;
const Person(this.name);
}
- 注意常量構(gòu)造函數(shù),只存在一個(gè)final屬性艰亮;
- 擁有常量構(gòu)造函數(shù)的類中闭翩,所有的成員變量必須是final修飾的;
工廠構(gòu)造函數(shù)
- Dart提供了
factory
關(guān)鍵字迄埃,用于通過(guò)工廠
去獲取對(duì)象疗韵;
- 普通的構(gòu)造函數(shù),會(huì)默認(rèn)返回創(chuàng)建出來(lái)的對(duì)象侄非,而工廠構(gòu)造函數(shù)蕉汪,
需要手動(dòng)返回一個(gè)對(duì)象
;
- 案例代碼:
main(List<String> args) {
final p1 = Person.withName("liyanyan");
final p2 = Person.withName("liyanyan");
print(identical(p1, p2)); //true
}
class Person {
//對(duì)象屬性
String name;
String color;
//類屬性
static final Map<String, Person> _nameCache = {};
static final Map<String, Person> _colorCache = {};
//工廠構(gòu)造函數(shù)
//1.根據(jù)key值從緩存中獲取對(duì)象逞怨,存在直接返回者疤,不存在
factory Person.withName(String name) {
if (_nameCache.containsKey(name)) {
return _nameCache[name];
} else {
final p = Person(name, "default");
_nameCache[name] = p;
return p;
}
}
factory Person.withColor(String color) {
if (_colorCache.containsKey(color)) {
return _colorCache[color];
} else {
final p = Person("default", color);
_colorCache[color] = p;
return p;
}
}
Person(this.name, this.color);
}
setter與getter方法
- setter方法中驹马,可使用關(guān)鍵字
set
;
- getter方法中,可使用關(guān)鍵字
get
糯累;
void main(List<String> args) {
Person person4 = Person.init("cccc", age: 26);
person4.setNamee("ssssss");
print(person4.name);
print(person4.getNamee());
person4.name = "gggg";
print(person4.name);
print(person4.getNamee());
}
class Person {
String name;
int age;
//其中age為可選參數(shù)
Person.init(this.name, {this.age});
//使用set,get關(guān)鍵字的setter算利,getter方法
set setName(String name) {
this.name = name;
}
String get getName {
return this.name;
}
//不采用set,get關(guān)鍵字的setter,getter方法
void setNamee(String name) {
this.name = name;
}
String getNamee() {
return this.name;
}
}
- setter與getter方法中使用了
set
與get
關(guān)鍵字泳姐,格式如代碼所示效拭;
- setter與getter方法中可以使用
箭頭函數(shù)
,更加簡(jiǎn)便胖秒;
- Dart中屬性的get/set方法名是可以任意仍使ⅰ;