Flutter-Dart語法二

面向?qū)ο筇匦?/h4>

1.類(class )

Dart是一個面向?qū)ο缶幊陶Z言,同時支持基于mixin的繼承機(jī)制。每個對象都是一個類的實例,所有的類都繼承于object。

1)構(gòu)造函數(shù)
構(gòu)造函數(shù)不能繼承。父類的命名構(gòu)造函數(shù)也不會被繼承,如果子類也有父類一樣命名構(gòu)造函數(shù),就必須在子類中自己實現(xiàn)該構(gòu)造函數(shù)。

  • 默認(rèn)構(gòu)造函數(shù):如果未顯式定義構(gòu)造函數(shù),會默認(rèn)一個參數(shù)為空的構(gòu)造函數(shù)。默認(rèn)構(gòu)造函數(shù)會調(diào)用父類的無參構(gòu)造函數(shù)。
class  Person { //未定義父類的時候,默認(rèn)繼承自O(shè)bject
  num x;
  num y;
  num z;
}

void main(List<String> args){
  var person = new Person();//調(diào)用默認(rèn)的構(gòu)造函數(shù)
  person.x = 10;   //使用點(.)引用實例變量或方法
  person.y = 11;
}
  • 類名構(gòu)造函數(shù):就是一個與類同名的函數(shù),關(guān)鍵字 this 是指當(dāng)前實例,只有在命名沖突時有效,否則dart會忽略處理。

class Point {
    int x;
    int y;
  //自己定義的類名構(gòu)造函數(shù)
  Point(int x, int y) {
      this.x = x;
    this.y = y;
   }
   
   // 在構(gòu)造函數(shù)里初始化成員屬性是很常見的事情,因此Dart開發(fā)了新的語法糖來簡化這種操作
   // 比如將Point的類名構(gòu)造構(gòu)造函數(shù)改寫成

   // Point(this.x, this.y);
  // 注意x,y的賦值會在構(gòu)造函數(shù)執(zhí)行之前完成.
   
}
void main(){
    var point = new Point(1, 2);
}

  • 命名構(gòu)造函數(shù):(類名.函數(shù)名)使用命名構(gòu)造函數(shù)可以為類提供多個構(gòu)造函數(shù)。
class Point {
  num x, y;

  Point(this.x, this.y);

  // 命名構(gòu)造函數(shù)
  Point.origin() {
    x = 0;
    y = 0;
  }
  // 簡化
  // Point.origin(this.x,this.y);
  
}

  • 重定向構(gòu)造函數(shù):有時構(gòu)造函數(shù)的唯一目的是重定向到同一類中的另一個構(gòu)造函數(shù)。重定向構(gòu)造函數(shù)的主體為空,構(gòu)造函數(shù)調(diào)用出現(xiàn)在冒號( :)之后 。
    大意就是在創(chuàng)建類時,我定義一個命名構(gòu)造函數(shù),但是這個構(gòu)造函式的主體我不實現(xiàn)。直接通過:調(diào)用另外一個構(gòu)造函數(shù),實現(xiàn)對外界傳入的參數(shù)的接收并賦值給內(nèi)部的變量。
class Point {
  num x, y;
  //類名構(gòu)造函數(shù)
  Point(this.x, this.y);
  // 命名構(gòu)造函數(shù)
 Point.order(this.x,this.y);
 Point.origin(num a,num b):this.order(a,b);  
 //重定向構(gòu)造函數(shù),origin構(gòu)造函數(shù)將外界的傳值,指向給了order構(gòu)造函數(shù)。
}

  • 工廠構(gòu)造函數(shù):在實現(xiàn)一個構(gòu)造函數(shù)時使用factory關(guān)鍵字,該構(gòu)造函數(shù)并不總是創(chuàng)建其類的新實例。例如,工廠構(gòu)造函數(shù)可能會從緩存中返回實例,也可能會返回子類型的實例。工廠構(gòu)造者對this沒有訪問權(quán)限。
class Logger {
  final String name;
  bool mute = false;

 // _cache是私有變量
 //_在名稱前,表示該變量為私有
  static final Map<String, Logger> _cache = <String, Logger>{};

  factory Logger(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
     } else {
       final logger = Logger._internal(name);
       _cache[name] = logger;
       return logger;
    }
  }

  Logger._internal(this.name);
  void log(String msg) {
    if (!mute) print(msg);
   }
}


調(diào)用:
var logger = Logger('UI');
logger.log('Button clicked');

  • 常量構(gòu)造函數(shù):如果你的類創(chuàng)建的對象從不改變,你可以創(chuàng)建一些編譯時的常量對象。因此,定義一個const構(gòu)造函數(shù),且保證所有的對象變量都是final。
class ImmutablePoint {
  final num x;
  final num y;
  const ImmutablePoint(this.x, this.y);
  static final ImmutablePoint origin =
      const ImmutablePoint(0, 0);
}

注意:如果父類中沒有默認(rèn)的構(gòu)造函數(shù),你必須手動調(diào)用父類的構(gòu)造函數(shù),在子類的構(gòu)造函數(shù)體之前通過(:) 指定調(diào)用父類構(gòu)造函數(shù),示例如下:

// Person類中沒有一個無參數(shù),未命名的構(gòu)造函數(shù)
class Person {
  String firstName;
  // 命名構(gòu)造函數(shù)
  Person.fromJson(Map data) {
    print('in Person');
  }
}

class Employee extends Person {
  // 你必須調(diào)用父類的super.fromJson(data).
  Employee.fromJson(Map data) : super.fromJson(data) {
    print('in Employee');
  }
}

main() {
  var emp = new Employee.fromJson({});
}


2.實例變量

聲明實例變量時,所有未初始化的實例變量的值為null。
每個實例變量都會自動生成一個getter方法,Non-final(沒有被final修飾)實例變量還會自定生成一個setter方法。

class Point{
  num x;//聲明實例變量x,初始化為空
  num y;//聲明實例變量y,舒適化為空
  num z = 0;//聲明實例變量z,初始化為0
  //如果在實例變量定義的時候初始化該變量(不是在構(gòu)造函數(shù)或者其他方法中初始化),該值是在實例化對象的時
  //候初始化的,也就是在構(gòu)造函數(shù)和初始化參數(shù)列表執(zhí)行之前。
  
}
void main() {
  var point = new Point();
  point.x = 4;              //使用setter方法對x變量賦值
  print(point.x == 4);      //輸出true 使用getter獲取x變量的值
  print(point.y == null);   //輸出true

}

靜態(tài)(類)變量:使用static關(guān)鍵字來實現(xiàn)類級別的變量和方法,靜態(tài)函數(shù)內(nèi)部不能訪問非靜態(tài)成員,非靜態(tài)函數(shù)能訪問靜態(tài)成員。

class Queue {
  // 靜態(tài)變量在使用之前不會初始化
  static const initialCapacity = 16;
  // ···
}

void main() {
  assert(Queue.initialCapacity == 16);
}

3.方法

1)實例方法
對象的實例函數(shù)可以訪問this。
import 'dart:math';

class Point {
  num x;
  num y;
  Point(this.x, this.y);

  num distanceTo(Point other) {
    var dx = x - other.x;
    var dy = y - other.y;
    return sqrt(dx * dx + dy * dy);
  }
}

2)類方法
使用static 修飾的方法,內(nèi)部不能訪問實例變量,沒有訪問this的權(quán)限。

class Page{
  // 添加 static 關(guān)鍵字
  static int currentPage = 1;
  num size ;
  
  //類方法
  static void scorllDown(){
    currentPage = 1;
    // 訪問實例變量報錯
    // size = 10;
    print("ScrollDown...");
  }
 
  void scorllUp(){
    currentPage ++;
    print("ScrollUp...");
  }
}

void main(List<String> args) {
  var page = new Page();
  // 調(diào)用類方法
  Page.scorllDown();
}


3)Getters和Setters 方法
Getters 和setters是用來設(shè)置和訪問對象屬性的特殊函數(shù)。每個實例變量都隱含的具有一個getter,如果變量不是final的則還有一個setter。使用get和set關(guān)鍵字定義getter和setter。

class Rectangle {
  num left;
  num top;
  num width;
  num height;

  Rectangle(this.left, this.top, this.width, this.height);

  // 定義兩個計算屬性:右和下。
  num get right             => left + width;
      set right(num value)  => left = value - width;
  num get bottom            => top + height;
      set bottom(num value) => top = value - height;
}

main() {
  var rect = new Rectangle(3, 4, 20, 15);
  assert(rect.left == 3);
  rect.right = 12;
  assert(rect.left == -8);
}

4)抽象函數(shù)

抽象函數(shù)是只定義函數(shù)接口但是沒有實現(xiàn)的函數(shù),由子類來實現(xiàn)該函數(shù)。如果用分號來替代函數(shù)體則這個函數(shù)就是抽象函數(shù)。

abstract class Doer {
  // ...定義實例變量和方法...

  void doSomething(); // 定義一個抽象方法.
}

class EffectiveDoer extends Doer {
  void doSomething() {
    // ...提供實現(xiàn),因此此處的方法不是抽象的...
  }
}

4.抽象類

使用abstract修飾符定義一個抽象類,一個不能被實例化的類。抽象類通常用來定義接口,如果你想實例化抽象類,你必須實現(xiàn)抽象類,才能被實例化。

// 這個類是抽象類,不能實例化
abstract class AbstractContainer {
  // ...定義構(gòu)造函數(shù), 變量, 方法...

  void updateChildren(); // 抽象方法.
}

class SpecializedContainer extends AbstractContainer {
  // ...定義更多的構(gòu)造方法, 方法...

  void updateChildren() {
    // ...實現(xiàn) updateChildren()...
  }

}


5.隱式接口

Dart中沒有哪個關(guān)鍵字是來定義接口的, 默認(rèn)情況下所有的類類都是都是隱式的接口,包括類的方法和屬性。當(dāng)將一個類當(dāng)做接口使用時,那么實現(xiàn)這個接口的類,必須實現(xiàn)這個接口中所有的方法。

// A person. 隱式接口包含greet().
class Person {
  // 在接口中,但僅在此庫中可見
  final _name;

  // 不在接口中,因為這是構(gòu)造函數(shù)
  Person(this._name);

  // 在接口中
  String greet(who) => 'Hello, $who. I am $_name.';
}

// 實現(xiàn)Person 接口
class Imposter implements Person {
  // 我們必須定義這個,但我們不使用它。
  final _name = "";

  String greet(who) => 'Hi $who. Do you know who I am?';
}

6.類的繼承

使用extends創(chuàng)建子類,super引用父類,子類可以重寫實例方法、getter和setter,使用@override注釋重寫,使用@proxy注釋來忽略警告

class Person {
  
 void run{
     print('people run');
 }
 
}

class Kids{
    @override
    void run{
     print('Kids run');
 }
}



重寫object的noSuchMethod()
當(dāng)用戶調(diào)用你定義的類中不存在的屬性與方法時,通過重寫noSuchMethod(),可以做出一些響應(yīng)。
class A {
  @override
  void noSuchMethod(Invocation invocation) {
    print('You tried to use a non-existent member: ' +
        '${invocation.memberName}');
  }
}


7.訪問控制

默認(rèn)類中的所有屬性和方法是public的。在dart中,可以在屬性和方法名前添加“_”使私有化。

class Animal{
  String _name;   // 私有屬性
  int age; 
  //默認(rèn)構(gòu)造函數(shù)的簡寫
  Animal(this._name,this.age);

  void printInfo(){   
    print("${this._name}----${this.age}");
  }

// 供外部調(diào)用私有屬性
  String getName(){ 
    return this._name;
  } 
  // 私有方法
  void _run(){
    print('這是一個私有方法');
  }

  execRun(){
    this._run();  //類里面方法的相互調(diào)用
  }
}


void main(){
 
 Animal a=new Animal('小狗', 3);

 print(a.getName());

  a.execRun();   //間接的調(diào)用私有方法

}

8.枚舉類型

枚舉中的每個值都有一個index索引,它返回枚舉聲明中值的從零開始的位置。例如,第一個值具有索引0,第二個值具有索引1。

enum Color { red, green, blue }

assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);

可以在switch語句中使用枚舉,如果不處理枚舉的所有值,將會收到警告。

9.泛型

泛型就是定義的一個類型,類型暫不確定,給使用給一個占位符給代替,在使用的時候可以給確定其定義的類型。

main() {
// 如果自己希望List只包含字符串對象。則可以定義為List<String>代表("list of string")。

   List Tech = new List<String>();
   Tech.addAll(['Android','IOS','Flutter']);
   Tech.add(42);//運行時報錯
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容