Flutter
已是整整一年前的事情了,以後由於工做重心主要放在了React Native
開發形式上Flutter
, 也是計劃系統性的從頭開始從新學習Dart
和Flutter
Dart
筆記主要就是記錄Dart
語言中的類和對象Dart
也是一門面向對象的開發語言,面向對象中很是重要的概念就是類,經過類的初始化建立一個對象html
Dart
中,定義類用class
關鍵字Object
的, 格式以下:class 類名 { 類型 成員名; 返回值類型 方法名(參數列表) { 方法體 } } 複製代碼
Dart
語言中, 在類中使用屬性(成員/實例變量)時, 有必要時是經過this
獲取的getsize
方法中並無加this
Dart
的開發風格中,在方法中一般使用屬性時,會省略this
,可是有命名衝突時,this
不能省略// 建立類 class Point { // 定義變量 int x; void getsize() { print('x = $x'); } } // 類的初始化 main(List<String> args) { // 從Dart2開始,new關鍵字能夠省略 var point = new Point(); point.x = 1; point.getsize(); } 複製代碼
Dart
語言中,若是類中沒有明確指定構造方法時,將默認擁有一個無參的構造方法()point
對象調用的就是默認的無參構造方法Dart
自己不支持函數的重載, 因此若是咱們明確的寫一個默認的構造方法,就會和咱們自定義的構造方法衝突class Student { String name; int age; Student(String name, int age) { this.name = name; this.age = age; } } 複製代碼
Dart
提供了一種更加簡潔的語法糖形式class Student1 { String name; int age; // 這裏和上面的Studeng的構造方法等價 Student1(this.name, this.age); } 複製代碼
Dart
又不支持函數的重載, 不能建立愛你相同名稱不一樣參數的構造方法class Model { String name; int age; Model(this.name, this.age); // 命名構造方法 Model.withNameAndAge(String name, int age) { this.name = name; this.age = age; } // 命名構造方法 Model.initJson(Map<String, Object> map) { this.name = map['name']; this.age = map['age']; } } // 初始化對象 main() { // 普通構造方法 var model0 = Model('name', 12); // 命名構造方法 var model1 = Model.withNameAndAge('titan', 12); var model2 = Model.initJson({'name': 'jun', 'age': 18}); } 複製代碼
幾種方式定義的屬性都是可變的, 若是定義的屬性是final
不可從新賦值的又該如何實現api
class Teacher { final String name; final int age; // 1. 這裏會有一個錯誤提示: All final variables must be initialized, but 'age' and 'name' are not Teacher(String name, int age) { //2. 這裏也會有一個錯誤提示: 'name' can't be used as a setter because it's final this.name = name; this.age = age; } } 複製代碼
Dart
中在執行下面{ }
中的代碼的時候, 表示Teacher
對象已經初始化完畢了{ }
以前, 必須保證name
和age
被初始化了final
修飾的屬性是不可被從新賦值的, 因此纔會報錯class Size { final double width; final double height; final double area; // 命名可選參數 Size(this.width, this.height, { this.area = 10 }); } 複製代碼
area
只能設置具體的數值, 不能設置表達式class Size { final double width; final double height; final double area; // 多個屬性使用逗號分隔 Size(double width, double height): this.width = width, this.height = height, this.area = width * height; } 複製代碼
name
變量來獲取一個對象class Point { String name; int age; Point(this.name, this.age); // 重定向的構造方法 Point.fromName(String name): this(name, 0); } // 使用方法 var point = Point.fromName("name"); print(point.age); // 輸出: 0 複製代碼
Dart
中判斷兩個對象是不是同一個的方法是經過函數identical
判斷, 返回值是一個布爾值// 普通構造函數 class Person { String name; int age; Person(this.name, this.age); } // 初始化列表 class Size { final double width; final double height; final double area; // 多個屬性使用逗號分隔 Size(double width, double height): this.width = width, this.height = height, this.area = width * height; } main(List<String> args) { var p1 = Person("name", 10); var p2 = Person("name", 10); // 判斷兩個對象是否是同一個 print(identical(p1, p2)); /// false var s1 = Size(10, 20); var s2 = Size(10, 20); // 判斷兩個對象是否是同一個 print(identical(s1, s2)); /// false } 複製代碼
Dart
中若是將構造方法前加const
進行修飾,那麼能夠保證相同的參數,建立出來的對象是相同的// 常量構造方法 class Teacher { final String name; const Teacher(this.name); } main(List<String> args) { // 常量構造方法 // 這裏的const不能夠省略 var t1 = const Teacher("name"); var t2 = const Teacher("name"); print(identical(t1, t2)); /// true // 這裏的const能夠省略 const t3 = Teacher("name"); const t4 = Teacher("name"); print(identical(t3, t4)); /// true print(identical(t1, t4)); /// true } 複製代碼
常量構造方法有一些注意點:緩存
final
修飾的.new
關鍵字,而是使用const
關鍵字const
修飾的標識符時,const
能夠省略.Dart
提供了factory
關鍵字, 用於經過工廠去獲取對象return
main(List<String> args) { var p1 = Person.fromName("titan"); var p2 = Person.fromName("titan"); print(identical(p1, p2)); // true } class Person { String name; // 用於緩存建立的對象, 避免大量的建立和銷燬對象 static final Map<String, Person> _cache = <String, Person>{}; factory Person.fromName(String name) { if (_cache.containsKey(name)) { return _cache[name]; } else { final p = Person(name); _cache[name] = p; return p; } } Person(this.name); } 複製代碼
Dart
中類定義的屬性默認是能夠直接被外界訪問的Dart
中也存在setter
和getter
方法, 用於監聽累的屬性被訪問的過程main() { var people = People('top'); people.setName = 'top'; print(people.getName); print(people.name); var person = Person('titan'); person.setName = 'jun'; print(person.getName); } class People { String name; // setter set setName(String value) { this.name = value; } // getter String get getName { return 'titanjun'; } People(this.name); } 複製代碼
setName
和getName
是自定義的, 你也能夠命名爲setterName
和getterName
等class Person { String name; // setter set setName(String value) => this.name = value; // getter String get getName => 'titanjun'; Person(this.name); } 複製代碼
Dart
中一樣支持類的繼承, 繼承使用extends
關鍵字,子類中使用super
來訪問父類super
顯式調用父類的某個構造方法class People { String name; People(this.name); void eat() { print('people -- eat'); } } class Person extends People { int age; Person(String name, int age): this.age = age, super(name); @override void eat() { // 這裏的super, 看我的需求是否調用 super.eat(); print('Person -- eat'); } } main(List<String> args) { var people = People('name'); people.eat(); var person = Person("top", 10); person.eat(); } 複製代碼
Dart
中抽象類是使用abstract
聲明的類Dart
中沒有具體實現的方法(沒有方法體),就是抽象方法abstract class Size { int width; int height; Size(this.width, this.height); void getSize(); int getArea() { return this.width * this.height; } } class Area extends Size { @override void getSize() { print('width = $width, height = $height'); } Area(int width, int height): super(width, height); } main(List<String> args) { // 實例化Size會報錯: Abstract classes can't be instantiated // var size = Size(20, 2); var area = Area(10, 2); area.getArea(); print(area.getArea()); } 複製代碼
在Dart
中咱們使用static
關鍵字來定義類成員和類方法微信
main() { var person = Person(); print(person.firstName); person.hide(); print(Person.lastName); Person.show(); } class Person { String firstName = 'top'; // 不能使用this調用靜態屬性 static String lastName = 'titanjun'; void hide() { print('titanjun'); } // 靜態方法 static void show() { print('https://www.$lastName.top'); } } 複製代碼
在Dart
中只有單繼承, 是不支持多繼承的, 可是咱們卻能夠經過其餘方式間接實現多繼承問題markdown
Dart
中的接口比較特殊, 沒有一個專門的關鍵字來聲明接口, 默認狀況下全部的類都是隱式接口Dart
開發中,咱們一般將用於給別人實現的類聲明爲抽象類Dart
中經過implements
來實現多繼承問題, 可是必須實現這個接口中的全部方法, 並且在方法的實現中不能調用super
方法abstract class Woman { void eat(); void student() { print("student"); } } class Man { void run() { print("runner"); } } class Student implements Woman, Man { @override void eat() { print("eat"); } @override void student() { print("student--student"); } @override void run() { // 這裏不能調用super方法 // super.run(); print("run"); } } main(List<String> args) { var stu = Student(); stu.eat(); stu.run(); stu.student(); } 複製代碼
implements
實現某個類時,類中全部的方法都必須被從新實現(不管這個類原來是否已經實現過該方法)class
定義類以外,也能夠經過mixin
關鍵字來定義一個類。mixin
定義的類用於被其餘類混入使用,經過with
關鍵字來進行混入mixin Runner { run() { print('在奔跑'); } } mixin Flyer { fly() { print('在飛翔'); } } // 這裏能夠對原方法不作任何實現 class Bird with Runner, Flyer { } main(List<String> args) { var bird = Bird(); bird.run(); bird.fly(); } 複製代碼
歡迎您掃一掃下面的微信公衆號,訂閱個人博客!ide