Dart是一門使用類和單繼承的面向對象語言,所有的對象都是類的實例,並且所有的類都是Object的子類。
面向對象編程(OOP)的三個基本特征是:封裝、繼承、多態
封裝:封裝是對象和類概念的主要特性。封裝,把客觀事物封裝成抽象的類,並且把自己的部分屬性和方法提供給其他對象調用, 而一部分屬性和方法則隱藏。
繼承:面向對象編程 (OOP) 語言的一個主要功能就是“繼承”。繼承是指這樣一種能力:它可以使用現有類的功能,並在無需重新編寫原來的類的情況下對這些功能進行擴展。
多態:允許將子類類型的指針賦值給父類類型的指針, 同一個函數調用會有不同的執行效果 。
-
構造函數
// class Person{ // String name='張三'; // int age=20; // //默認構造函數 // Person(){ // print('這是構造函數里面的內容 這個方法在實例化的時候觸發'); // } // void printInfo(){ // print("${this.name}----${this.age}"); // } // } // class Person{ // String name; // int age; // //默認構造函數 // Person(String name,int age){ // this.name=name; // this.age=age; // } // void printInfo(){ // print("${this.name}----${this.age}"); // } // } class Person{ String name; int age; //默認構造函數的簡寫,通常這么用 Person(this.name,this.age); void printInfo(){ print("${this.name}----${this.age}"); } } void main(){ Person p1=new Person('張三',20); p1.printInfo(); Person p2=new Person('李四',25); p2.printInfo(); }
區別1:與java的構造函數有點不同的是,dart里面構造函數可以寫多個。
class Person{ String name; int age; //默認構造函數的簡寫 Person(this.name,this.age); Person.now(){ print('我是命名構造函數'); } Person.setInfo(String name,int age){ this.name=name; this.age=age; } void printInfo(){ print("${this.name}----${this.age}"); } } void main(){ // var d=new DateTime.now(); //實例化DateTime調用它的命名構造函數 // print(d); //Person p1=new Person('張三', 20); //默認實例化類的時候調用的是 默認構造函數 //Person p1=new Person.now(); //命名構造函數 Person p1=new Person.setInfo('李四',30); p1.printInfo();
}
區別2:Dart中沒有 public private protected這些訪問修飾符,但是我們可以使用_把一個屬性或者方法定義成私有。
區別3:getter與setter修飾符
class Rect{ double height; double width; Rect(this.height,this.width); // getter修飾符 get area{ return this.height * this.width; } // setter修飾符 set areaHeight(value){ this.height = value; } } void main() { Rect r = Rect(10.0,5.0); print(r.area); r.areaHeight = 20.0; print(r.area); }
區別4:Dart可以在構造函數體運行之前初始化實例變量
class Rect{ int height; int width; Rect():height=2,width=10{ print("${this.height}---${this.width}"); } getArea(){ return this.height*this.width; } } void main(){ Rect r=new Rect(); print(r.getArea()); }
-
Dart中的靜態成員與靜態方法
class Person { static String name = '張三'; static void show() { print(name); } } void main() { print(Person.name); Person.show(); }
與java語法基本一樣。
靜態方法不能訪問非靜態成員,只能訪問靜態成員。
非靜態方法可以訪問非靜態成員,也可以訪問靜態成員。
-
Dart中的對象操作符
條件運算符——?
class Person{ String name; int age; Person(this.name,this.age); void printInfo() { print("${this.name}---${this.age}"); } } void main() { Person p; p.printInfo(); // NoSuchMethodError: The method 'printInfo' was called on null. p?.printInfo(); // 如果p不為null時,執行printInfo方法。否則跳過。 }
類型轉換(類似Java中的強制轉換)——as
(p as Person).printInfo();
類型判斷——is
if(p is Person){ ... }
級聯操作——..
p..name = "李四" ..age = 30 ..printInfo();
- Dart中的super(用於“繼承”)
super關鍵字可以傳遞參數給父類
class Person { String name; num age; Person(this.name,this.age); void printInfo() { print("${this.name}---${this.age}"); } } class Web extends Person{ String sex; Web(String name, num age,String sex) : super(name, age){ // super關鍵字可以把name和age的值傳遞給父類 this.sex=sex; } run(){ print("${this.name}---${this.age}--${this.sex}"); } } void main(){ Web w=new Web('張三', 12,"男"); w.printInfo(); w.run(); }
super關鍵字可以調用父類方法
class Person { String name; num age; Person(this.name,this.age); void printInfo() { print("${this.name}---${this.age}"); } work(){ print("${this.name}在工作..."); } } class Web extends Person{ Web(String name, num age) : super(name, age); run(){ print('run'); super.work(); //子類調用父類的方法 } }
-
Dart中的抽象類
Dart中抽象類: Dart抽象類主要用於定義標准,子類可以繼承抽象類,也可以實現抽象類接口。
1、抽象類通過abstract 關鍵字來定義
2、Dart中的抽象方法不能用abstract聲明,Dart中沒有方法體的方法我們稱為抽象方法。
3、如果子類繼承抽象類必須得實現里面的抽象方法
4、如果把抽象類當做接口實現的話必須得實現抽象類里面定義的所有屬性和方法。
5、抽象類不能被實例化,只有繼承它的子類可以
extends抽象類 和 implements的區別:
1、如果要復用抽象類里面的方法,並且要用抽象方法約束子類的話我們就用extends繼承抽象類
2、如果只是把抽象類當做標准的話我們就用implements實現抽象類
abstract class Animal{ eat(); //抽象方法 run(); //抽象方法 printInfo(){ print('我是一個抽象類里面的普通方法'); } } class Dog extends Animal{ @override eat() { print('小狗在吃骨頭'); } @override run() { print('小狗在跑'); } } class Cat extends Animal{ @override eat() { print('小貓在吃老鼠'); } @override run() { print('小貓在跑'); } } main(){ Dog d=new Dog(); d.eat(); d.printInfo(); Cat c=new Cat(); c.eat(); c.printInfo(); // Animal a=new Animal(); //抽象類沒法直接被實例化 }
-
Dart中的多態
Dart中的多態:
允許將子類類型的指針賦值給父類類型的指針, 同一個函數調用會有不同的執行效果 。子類的實例賦值給父類的引用。
多態就是父類定義一個方法不去實現,讓繼承他的子類去實現,每個子類有不同的表現。
abstract class Animal{ eat(); //抽象方法 } class Dog extends Animal{ @override eat() { print('小狗在吃骨頭'); } } class Cat extends Animal{ @override eat() { print('小貓在吃老鼠'); } } main(){ Dog d=new Dog(); d.eat(); Cat c=new Cat(); c.eat(); }
-
Dart中的接口
和Java一樣,dart也有接口,但是和Java還是有區別的。
首先,dart的接口沒有interface關鍵字定義接口,而是普通類或抽象類都可以作為接口被實現。
同樣使用implements關鍵字進行實現。
但是dart的接口有點奇怪,如果實現的類是普通類,會將普通類和抽象中的屬性和方法全部需要覆寫一遍。
而因為抽象類可以定義抽象方法,普通類不可以,所以一般如果要實現像Java接口那樣的方式,一般會使用抽象類。
建議使用抽象類定義接口。
/* 定義一個DB庫 支持 mysql mssql mongodb mysql mssql mongodb三個類里面都有同樣的方法 */ abstract class Db{ //當做接口 接口:就是約定 、規范 String uri; //數據庫的鏈接地址 add(String data); save(); delete(); } class Mysql implements Db{ @override String uri; Mysql(this.uri); @override add(data) { print('這是mysql的add方法'+data); } @override delete() { return null; } @override save() { return null; } remove(){ return null; } } class MsSql implements Db{ @override String uri; @override add(String data) { print('這是mssql的add方法'+data); } @override delete() { return null; } @override save() { return null; } } main() { Mysql mysql=new Mysql('xxxxxx'); mysql.add('1243214'); }
-
Dart中的mixins
mixins的中文意思是混入,就是在類中混入其他功能。
在Dart中可以使用mixins實現類似多繼承的功能
因為mixins使用的條件,隨着Dart版本一直在變,這里講的是Dart2.x中使用mixins的條件:
1、作為mixins的類只能繼承自Object,不能繼承其他類
2、作為mixins的類不能有構造函數
3、一個類可以mixins多個mixins類
4、mixins絕不是繼承,也不是接口,而是一種全新的特性
class Person{ String name; num age; Person(this.name,this.age); printInfo(){ print('${this.name}----${this.age}'); } void run(){ print("Person Run"); } } class A { String info="this is A"; void printA(){ print("A"); } void run(){ print("A Run"); } } class B { void printB(){ print("B"); } void run(){ print("B Run"); } } class C extends Person with B,A{ C(String name, num age) : super(name, age); } void main(){ var c=new C('張三',20); c.printInfo(); // 張三----20 c.printB(); //B print(c.info); // this is A c.run(); // A Run(如果有同樣的方法,取最后的mixins類的方法) }
-
Dart中的泛型
泛型方法
void main() { T getData<T>(T value){ return value; } String result = getData<String>("你好"); print(result); }
泛型類
class PrintClass<T> { List list = new List<T>(); void add(T value){ this.list.add(value); } void printInfo(){ for(var i = 0; i < this.list.length; i++) { print(this.list[i]); } } } void main() { PrintClass p = new PrintClass<String>(); p.add("你好"); p.add("再見"); p.printInfo(); }
泛型接口
abstract class Cache<T>{ getByKey(String key); void setByKey(String key, T value); } class FlieCache<T> implements Cache<T>{ @override getByKey(String key) { return null; } @override void setByKey(String key, T value) { print("我是文件緩存 把key=${key} value=${value}的數據寫入到了文件中"); } } class MemoryCache<T> implements Cache<T>{ @override getByKey(String key) { return null; } @override void setByKey(String key, T value) { print("我是內存緩存 把key=${key} value=${value} 寫入到了內存中"); } } void main(){ MemoryCache m1=new MemoryCache<String>(); m1.setByKey('index', '首頁數據'); MemoryCache m2=new MemoryCache<Map>(); m2.setByKey('index', {"name":"張三","age":20}); }