Flutter之路-Dart篇

Dart的一些基础知识可以看Dart中文网,网上也有很多入门教程。这个系列只是我在学习过程很有用,但一些基础教程中未提及的。

Dart和Java在很多方面很相似,但也有很多不一样的地方,比如:

  • 在 Dart 中没有诸如 public、private、protected 这样的关键词。以 _ 开头,则该标识符 在库内是私有的
  • Dart2中,可以不使用new关键字创建,也可以使用。
  • Dart中一切都是对象,方法也是对象并且具有一种类型Function。
  • Dart中变量初始值为null,即使是int类型也是null。
  • ..........

函数

可选参数

  1. 可选命名参数

    调用方法的时候,你可以使用这种形式 paramNamevalue 来指定命名参数。例如:
    enableFlags(bold: true, hidden: false);

    在定义方法的时候,使用 {param1param2, …} 的形式来指定命名参数:

    /// Sets the [bold] and [hidden] flags to the values
    /// you specify.
    enableFlags({bool bold, bool hidden}) {
      // ...
    }

    可选命名参数常用于类的构造函数,看参看类-构造函数可选命名参数

  2. 可选位置参数

    把一些方法的参数放到 [] 中就变成可选 位置参数了:
    String say(String from, String msg, [String device]) {
      var result = '$from says $msg';
      if (device != null) {
        result = '$result with a $device';
      }
      return result;
    }

    下面是不使用可选参数调用上面方法 的示例:

    assert(say('Bob', 'Howdy') == 'Bob says Howdy');

    下面是使用可选参数调用上面方法的示例:

    assert(say('Bob', 'Howdy', 'smoke signal') ==
        'Bob says Howdy with a smoke signal');

     

Dart中类的定义、继承、重载和Java差不多,如果你会Java那Dart的面向对象也就很简单。但还是存在一些差异性的地方

例如:实列化的时一般是new Point();,Dart中new是可选的,Java是必须的。

 

构造函数

常见的构造函数定义和Java一样,定义一个和类名字一样的方法就定义了一个构造函数,还可以带有其他可选的标识符:

class Point {
  num x;
  num y;

  Point(num x, num y) {
    // There's a better way to do this, stay tuned.
    this.x = x;
    this.y = y;
  }
}

由于把构造函数参数赋值给实例变量的场景太常见了, Dart 提供了一个语法糖来简化这个操作:

class Point {
  num x;
  num y;

  // Syntactic sugar for setting x and y
  // before the constructor body runs.
  Point(this.x, this.y);
}

 

构造函数可选命名参数

在看Flutter一些控件的源码时,经常能看到以下代码

const Text(this.data, {
    Key key,
    this.style,
    this.strutStyle,
    this.textAlign,
    this.textDirection,
    this.locale,
    this.softWrap,
    this.overflow,
    this.textScaleFactor,
    this.maxLines,
    this.semanticsLabel,
  }) : assert(data != null),
       textSpan = null,
       super(key: key);

构造函数也是函数,所以同样适用函数的可选命名参数,在加上Dart 提供了一个语法糖,所以可像以下代码调用

new Text('红色+黑色删除线+25号',
    style: TextStyle(
        color: const Color(0xffff0000),
    ),
)

初始化参数列表

在构造函数体执行可以初始化实例参数, 使用逗号分隔初始化表达式。

class Point {
  num x;
  num y;

  Point(this.x, this.y);

  // Initializer list sets instance variables before
  // the constructor body runs.
  Point.fromJson(Map jsonMap)
      : x = jsonMap['x'],
        y = jsonMap['y'] {
    print('In Point.fromJson(): ($x, $y)');
  }
}

警告: 初始化表达式等号右边的部分不能访问 this

初始化列表非常适合用来设置 final 变量的值。

重定向构造函数

有时候一个构造函数会调动类中的其他构造函数。 一个重定向构造函数是没有代码的,在构造函数声明后,使用 冒号调用其他构造函数。

class Point {
  num x;
  num y;

  // The main constructor for this class.
  Point(this.x, this.y);

  // Delegates to the main constructor.
  Point.alongXAxis(num x) : this(x, 0);
}

调用超类构造函数

默认情况下,子类的构造函数会自动调用超类的 无名无参数的默认构造函数。 超类的构造函数在子类构造函数体开始执行的位置调用。 如果提供了一个 initializer list(初始化参数列表) ,则初始化参数列表在超类构造函数执行之前执行。

如果超类没有无名无参数构造函数, 则你需要手工的调用超类的其他构造函数。 在构造函数参数后使用冒号 (:) 可以调用 超类构造函数。

class Person {
  String firstName;

  Person.fromJson(Map data) {
    print('in Person');
  }
}

class Employee extends Person {
  // Person does not have a default constructor;
  // you must call super.fromJson(data).
  Employee.fromJson(Map data) : super.fromJson(data) {
    print('in Employee');
  }
}

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

  // Prints:
  // in Person
  // in Employee
  if (emp is Person) {
    // Type check
    emp.firstName = 'Bob';
  }
  (emp as Person).firstName = 'Bob';
}

下面是构造函数执行顺序:

  1. initializer list(初始化参数列表)
  2. superclass’s no-arg constructor(超类的无名构造函数)
  3. main class’s no-arg constructor(主类的无名构造函数)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值