Dart的类扩展、可选类型扩展

extends

继承。 Dart里没有多继承。根类是Object.

abstract class StatefulWidget extends Widget 
 
 
abstract class StatelessWidget extends Widget


mixin ( With)

混入(mixin)。通过非继承的方式使用另一个类的函数。

//flutter 里用到混用的类
abstract class Diagnosticable with DiagnosticableMixin 

示例

class A {
  a(){
    print("this is a function!");
  }
}
 
mixin aa {
  aaFunction(){
    print("this is aa function! ha ha !");
  }
}
 
class Aa with aa,A
{
}
 
//调用
Aa()
    ..a()
    ..aaFunction();


implements


实现。dart里没有interface 关键字。implements 与OC 的 delegate 类似。

eg :flutter 里的Element 和 List。 BuildContext 和 Iterable 都抽象类(abstract)只是提供接口,然后在 implements 的类里去实现。Flutter里用到的 implements的类

abstract class Element extends DiagnosticableTree implements BuildContext 
//将BuildContext这个类的成员都看做是接口的定义
abstract class List<E> implements EfficientLengthIterable<E>
  
abstract class EfficientLengthIterable<T> extends Iterable<T>//里实现了快速遍历等方法


实现implements类的方法前加 @override

//  Element 里实现的BuildContext 的方法
@override
  InheritedWidget inheritFromElement(InheritedElement ancestor, { Object aspect }) {
    assert(ancestor != null);
    _dependencies ??= HashSet<InheritedElement>();
    _dependencies.add(ancestor);
    ancestor.updateDependencies(this, aspect);
    return ancestor.widget;
  }


class AB implements B ,则A里必须实现B里的全部方法,即使B类里有实现该方法。Missing concrete implementation of B

而mixin的类则不必需实现,如实现了则优先调用ABclass里实现的方法

class A {
  a(){
    print("this is a function!");
  }
}
 
mixin aa {
  aaFunction(){
    print("this is aa function! ha ha !");
  }
}
 
class B {
  b(){
    print("this is b ! b B");
  }
  bB(){
    print("this B class bB Function !");
  }
}
 
abstract class BB {
  bb();
}
 
class AB with aa,A implements BB, B
{
  @override
  a() {
    print("this is AB class a Function !");
  }
 
  @override
  bb() {
   print("this is Aa class bb Function !");
  }
 
  @override
  b() {
    print("this is Aa class b Function !");
  }
 
  @override
  bB() {
    print("this is Aa class bB Function !");
  }
 
}


调用结果

AB()
    ..a()
    ..aaFunction()
    ..b()
    ..bb();
//打印
I/flutter (29103): this is AB class a Function !
I/flutter (29103): this is aa mixin function! ha ha !
I/flutter (29103): this is Aa class b Function !
I/flutter (29103): this is Aa class bb Function !

以上三种关系可以同时存在,但是有前后顺序: extends -> with (mixin) -> implements

<>
泛型。里为指定的泛型的类型

eg. 我们去子类化声明State类的方式为

class TabBarState extends State <TableBarPage> 
///<TableBarPage> 表明TabBarState 的父类State是用来表示TableBarPage的状态
还有就是用于List里的泛型,与OC里用法一致

List<Widget> pages = List<Widget>();///List里为Widget 或其子类
 

用Extension对类进行扩展

一般情况要扩展一个类,需要继承这个类,这是在大多数java或者其他面向对象语言中要做的事情。

但是有些时候扩展类并不是特别好用,首先在有些语言中,有些类是禁止被扩展的。即使可以被扩展,但是扩展之后的类是一个新的类,而不是原来的父类,所以在使用的过程中可能会出现一些类型转换的问题。

那么在dart中是怎么解决这个问题的呢?

dart中extension的使用(2.7的新特性)
dart在2.7之后,引入了extension,用来对类的方法进行扩展。

到底怎么扩展呢?我们举个例子.

我们可以将字符串转换为int,通过调用int的parse方法,如下所示:

int.parse('18')

但是通过int类来进行转换通常不太直观,我们希望能够在String类中提供一个toInt的方法,可以直接调用,将字符串转换成为int。

'18'.toInt()

但是很遗憾,String并没有提供toInt的方法,所以我们可以通过extension来对String进行扩展:

extension StringToNumber on String {
  int toInt() {
    return int.parse(this);
  }
  // ···
}

如果这个文件的名字叫做string_to_number.dart,那么我们可以这样使用:

import 'string_to_number.dart';
// ···
print('18'.parseInt()); 


dart中方法扩展最为方便的是,你只要引入对应的lib,使用的时候甚至都不知道在使用lib的扩展。

当然,并不是所有的类都可以使用extention进行扩展。比如dynamic类型就不能进行扩展。

但是使用var类型,只要该类型可以被推断出来,那么就可以使用extention扩展。

API冲突
既然可以对lib进行扩展,那么就有可能出现API冲突的情况。那么怎么解决API冲突呢?

比如我们需要使用两个lib扩展文件,extention1.dart和extention2.dart.但是两个扩展文件中都定义了parseInt方法对String进行扩展。

如果同时引用的话,就会出现问题。

这时候可以使用show或者hide来限制具体使用哪一个扩展文件的中的方法。

import 'extention1.dart';

import 'extention2.dart' hide StringToNumber2;

print('18'.parseInt());

还有一种情况就是显示调用extension,如下所示:

import 'extention1.dart';

import 'extention2.dart';

print(StringToNumber('18').parseInt());
print(StringToNumber2('18').parseInt());

通过extention的名字来进行区分。

如果两个extention的名字也相同的话,那么可以通过prefix来进行区分:

import 'extention1.dart';

import 'extention2.dart' as ext2;

print(StringToNumber('18').parseInt());
print(ext2.StringToNumber('18').parseInt());

extention的实现


实现扩展很简单,实现语法如下:

extension <extension name> on <type> {
  (<member definition>)*
}

下面是一个扩展String的例子:

extension NumberParsing on String {
  int parseInt() {
    return int.parse(this);
  }

  double parseDouble() {
    return double.parse(this);
  }
}


extension还可以扩展泛型参数:

extension MyFancyList<T> on List<T> {
  int get doubleLength => length * 2;
  List<T> operator -() => reversed.toList();
  List<List<T>> split(int at) => [sublist(0, at), sublist(at)];
}

上面的实现是对List 进行扩展,添加了getter,操作符和split方法。


可选类型扩展的例子:

    final String? a = null;
    DDLog(a.runtimeType); // Null
    DDLog(a.or(() => "456")); // 456
    DDLog(a.or((){
      return "111";
    })); // 111
extension GetDynamicExt<T> on T {

  /// 返回可选值或者 `else` 闭包返回的值
  /// 例如. nullable.or(else: {
  /// ... code
  /// })
  T or(T Function() block) {
    return this ?? block();
  }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值