动态

详情 返回 返回

Flutter/Dart第17天:Dart類繼承 - 动态 详情

Dart官方文檔:https://dart.dev/language/extend

重要説明:本博客基於Dart官網文檔,但並不是簡單的對官網進行翻譯,在覆蓋核心功能情況下,我會根據個人研發經驗,加入自己的一些擴展問題和場景驗證。

類繼承(extends/super)

Dart語言和Java語言一樣,也是通過extends關鍵字創建子類,通過super關鍵字引用父類:

class Television {
  void turnOn() {
    _illuminateDisplay();
    _activateIrSensor();
  }
  // ···
}

// `extends`繼承父類
class SmartTelevision extends Television {
  void turnOn() {
    // `super`引用父類
    super.turnOn();
    _bootNetworkInterface();
    _initializeMemory();
    _upgradeApps();
  }
  // ···
}

成員重寫(override)

子類可以重寫父類的成員方法,包括操作符、getters和setters等。通過@override註解表明重寫父類的成員方法:

class Television {
  // ···
  set contrast(int value) {...}
}

class SmartTelevision extends Television {
  @override
  set contrast(num value) {...}
  // ···
}

子類重寫方法的申明必須與父類被重新的方法相匹配,匹配的方式有以下幾種:

  • 返回類型必須與重寫方法的返回類型相同(或子類型)(如:父類方法返回類型是num,那麼子類的返回類型必須是num或子類,如int等)。
  • 參數類型必須與重寫方法的參數類型相同(或超類型)(如:上訴代碼樣例,SmartTelevision子類的參數類型num是父類int的超類)。
  • 位置參數的數量必須相同(如:父類接收3個位置參數,則子類必須也是3個位置參數)。
  • 泛型方法不能重寫非泛型方法,反之也一樣,非泛型方法不能重寫泛型方法。

最佳實戰:重寫方法時,儘量避免縮寫參數類型的範圍,即儘量避免參數發生向下轉換(如父類是num類型,而子類是int類型等),因為這樣做可能會引發類型轉換錯誤。當然,如果我們確定不會發生錯誤,也可以這樣做。

特別注意:當我們重寫了相等==操作符,則必須重寫hashCodegetter方法:

class Person {
  final String firstName, lastName;

  Person(this.firstName, this.lastName);

  // 重寫 `hashCode` 獲取方法
  @override
  int get hashCode => Object.hash(firstName, lastName);

  // 重寫 `==` 操作符
  @override
  bool operator ==(Object other) {
    return other is Person &&
        other.firstName == firstName &&
        other.lastName == lastName;
  }
}

void main() {
  var p1 = Person('Bob', 'Smith');
  var p2 = Person('Bob', 'Smith');
  var p3 = 'not a person';
  assert(p1.hashCode == p2.hashCode);
  assert(p1 == p2);
  assert(p1 != p3);
}

noSuchMethod()方法

若需要在訪問不存在的方法或實例變量時,我們代碼能做出響應(而不是拋出NoSuchMethodError錯誤),則我們可以重寫noSuchMethod()方法:

class A {
  // 重寫`noSuchMethod`方法,避免`NoSuchMethodError`錯誤
  @override
  void noSuchMethod(Invocation invocation) {
    print('You tried to use a non-existent member: '
        '${invocation.memberName}');
  }
}

在Dart語言中,除了以下幾種情況外,我們不可能調用一個不存在的方法(編譯就出錯):

  • 對象是dynamic動態類型,運行時才能確定具體類型。
  • 對象是靜態類型,存在未實現的方法,且它實現了noSuchMethod()方法(即它不是繼承Object類型的noSuchMethod()方法)。

我的本博客原地址:https://ntopic.cn/p/2023102501


Add a new 评论

Some HTML is okay.