03-Dart语法--对象的构建者以及操控者

typedef

//没返回值,则只要参数匹配就行了,如果定义了返回值,则返回值不一样会报错
typedef Fun1(int a, int b);
typedef Fun2(T a, K b);

int add(int a, int b) {
  print('a + b');
  return a + b;
}

class Demo1 {
  Demo1(int f(int a, int b), int x, int y) {
    var sum = f(x, y);
    print("sum1 = $sum");
  }
}

class Demo2 {
  Demo2(Fun1 f, int x, int y) {
    var sum = f(x, y);
    print("sum2 = $sum");
  }
}

class Demo3 {
  Demo3(Fun2 f, int x, int y) {
    var sum = f(x, y);
    print("sum3 = $sum");
  }
}

goTypedef() {
  Demo1 d1 = new Demo1(add, 2, 3);
  Demo2 d2 = new Demo2(add, 5, 6);
  Demo3 d3 = new Demo3(add, 5, 6);
}

泛型

Dart 的泛型类型是固化的,在运行时有也可以判断具体的类型。

void goGeneric() {
  //list
  var colors1 = ['red', 'green', 'blue'];
  //Map
  var colors2 = {
    'first': 'red',
    'second': 'green',
    'third': 'blue'
  };

  var colors3 = new List();
  colors3.addAll(['red', 'green', 'blue']);
  print(colors3 is List); //java在运行时不判断泛型
}

控制语句

  • if and else
  • for loops
  • while and do-while loops
  • break and continue
  • switch and case
  • assert

for

//List 和 Set 等实现了 Iterable 接口的类还支持 for-in 形式的遍历
void goFor(){
  //for-in  形式
  var collection = [0, 1, 2];
  for (var x in collection) {
    print(x);
  }

  //forEach形式
  List list = ['a','b','c'];
  list.forEach((i)=>print(i));
}

while and do-while

void goWhile(){
  int a = 1;
  while(a < 5){
    print('goWhile a = $a');
    a++;
    if(a == 4){
      break;
    }
  }

  int b = 0;
  do{
    b ++;
    print('goWhile b = $b');
  }while(b < 0);
}

Switch and case,enum

  1. 每个非空的 case 语句都必须有一个 break 语句。 另外还可以通过 continue、throw 或者 return 来结束非空 case 语句。
  2. case都必须是编译时常量,这些常量必须符合以下条件:
    • 都是int的实例
    • 都是String的实例
    • 都是同一个类的实例且该类必须从Object继承了==的实现
    • switch使用==比较,class必须没有覆写==操作符
void goSwitch() {
  switch ("flutter") {
    case "jimmy":
      print('hello jimmy');
      break;
    case "flutter":
      print("hello flutter");
      break;
  }
  //switch中使用枚举需要把所有枚举值case一边,或者加default,否则会有警告
  Color color = Color.red;
  switch (color) {
    case Color.red:
      break;
    case Color.blue:
      break;
    //case Color.green:
      //break;
    default:
  }
  switch (color) {
    case Color.red:
      print("color.red");
      continue goGreen;
    case Color.blue:
      print("color.blue");
      break;
    goGreen:
    case Color.green:
      print("color.green");
      break;
    default:
  }
}

enum Color { red, green, blue }
void goEnum() {
  print('Color.red = ${Color.red}');
  print('Color.red = ${Color.red.index}');
  
  //values 返回所有枚举值
  List colors = Color.values;
  assert(colors[2] == Color.blue);
}

Exceptions(异常)

Throw 可以抛出任意对象

void goThrow() {
  try {
    getName2();
  } catch (e,s) {
    //函数 catch() 可以带有一个或者两个参数, 第一个参数为抛出的异常对象,
    // 第二个为堆栈信息 (一个 StackTrace 对象)。
    print("goThrow catch = $e,$s");
  } finally {
    print('goThrow finally');
  }
}

getName2() {
  //你可以使用on 或者 catch 来声明捕获语句,也可以同时使用。
  // 使用 on 来指定异常类型,使用 catch 来捕获异常对象。
  try {
    getName();
  } on Exception {
    print("getName2:Exception");
  } on NullThrownError catch (e) {
    print("getName2 on = $e");
    //使用 rethrow 关键字可以 把捕获的异常给 重新抛出。
    rethrow;
  } catch (e) {
    // 没指定类型,捕获任何异常类型
    print("getName2 catch $e");
  }
}

getName() {
  if (true) {
    throw new NullThrownError();
  }
}

构造函数

//java中写法
class Point1 {
  num x;
  num y;

  Point1(num x, num y) {
    this.x = x;
    this.y = y;
  }
}

//dart建议写法
class Point2 {
  num x;
  num y;
  Point2(this.x, this.y);
}

命名构造函数

Dart语言是不支持方法重载的。构造函数的重载也不支持,但是它支持命名构造函数。

Point2.fromJson(Map json) {
    x = json['x'];
    y = json['y'];
}

重定向构造函数

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

Point2.alongXAxis(num x) : this(x, 0);

超类构造函数

class Point3 extends Point2 {
  Point3.fromJsonCustom(Map data):super.fromJson(data){
    print('in point');
  }
}
void goPoint3(){
  var point3 = new Point3.fromJsonCustom({'x':5,'y':6});
  var px = point3.x;
  var py = point3.y;
  print('x=$px  y=$py');

  var point2 = new Point2.alongXAxis(15);
  var px2 = point2.x;
  var py2 = point2.y;
  print('x2=$px2,y2=$py2');
}

Initializer list(初始化列表)

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

import 'dart:math';

class Point3 {
  final num x;
  final num y;
  final num distanceFromOrigin;

  Point3(x, y)
      : x = x,
        y = y,
        distanceFromOrigin = sqrt(x * x + y * y);
}

void goPoint3() {
  var p = new Point3(2, 3);
  print(p.distanceFromOrigin);
}

工厂构造函数

class A {
  String name;
  static A _cache;//注意工厂模式无法使用this.所以这儿要静态的
  A._newObject(this.name);//需要一个命名构造函数来生产实例

  factory A(name1){
    if (A._cache==null) {
      A._cache =new A._newObject(name1);
    }
    return A._cache;//没有实例创建实例对象并缓存,缓存中有实例对象,直接使用
  }
}
void goFactory(){
  A a =new A('HelloWorld');
  print(a.name);

  A b = new A('helloDart');
  print(b.name);

  print(a==b);
  /*输出:
      HelloWorld
      HelloWorld
      true
  */
}

Getters and setters

class GetAndSet {
  num a;
  num b;
  GetAndSet(this.a,this.b);

  set c (num value){//(先)赋值
    print('set c');
    a = value + b;//随便定义一个方法:重新给a赋值
  }
  num get c{//(再)取值
    print('get c');
    return a + b;
  }
}
goGetAndSet(){
  var i =new GetAndSet(5, 9);
  i.c = 4;//给c赋值
  var k = i.c;//获取c的值
  print('i.a = ${i.a},i.b = ${i.b},k = $k');
}

抽象类

//使用 abstract 修饰符来定义一个抽象类,该类不能被实例化。抽象类在定义接口的时候非常有用,实际上抽象中也包含一些实现。如果你想让你的抽象类被实例化,请定义一个 工厂构造函数 。
abstract class Car {// 这个类是抽象类,因此不能被实例化。
  run();// 抽象方法。
  space() {}
}

//下面的类不是抽象类,因此它可以被实例化,即使定义了一个抽象方法:
class Bus extends Car {
  int width = 4;//设置默认值
  Bus(this.width);
    
  @override
  run() {
    print('Bus 起飞跑');
  }
}

接口实现

  1. 每个类都隐式的定义了一个包含所有实例成员的接口, 并且这个类实现了这个接口。
  2. 如果你想创建类A来支持类B的api,而不想继承B的实现,则类A应该实现类B的接口。
  3. 一个类可以通过 implements 关键字来实现一个或者多个接口, 并实现每个接口定义的 API。
 // 一个 person ,包含 greet() 的隐式接口。
 class Person {
     // 在这个接口中,只有库中可见。
     final _name;

     // 不在接口中,因为这是个构造函数。
     Person(this._name);

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

 //  Person 接口的一个实现。
 class Imposter implements Person {
     // 我们不得不定义它,但不用它。
     final _name = "";

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

 greetBob(Person person) => person.greet('bob');

 main() {
    print(greetBob(new Person('kathy')));
    print(greetBob(new Imposter()));
 }

//这里是具体说明一个类实现多个接口的例子:
 class Point implements Comparable, Location {
    // ...
 }

mixin

特性:

  1. 传统的接口概念中,并不包含实现部分,而Mixin包含实现。

如何定义一个mixin的类:

  1. 定义一个类继承 Object
  2. 该类没有构造函数
  3. 不能调用 super ,则该类就是一个 mixin
//可以是抽象的,也可以不是
class S {
//   a() {
//     print("S.a");
//   }
//   b() {
//     print("S.b");
//   }
//   c() {
//     print("S.c ");
//   }
}
class A {
  a() {
    print("A.a");
  }
  b() {
    print("A.b");
  }
}
class B {
  a() {
    print("B.a");
  }
  b() {
    print("B.b");
  }
  c() {
    print("B.c ");
  }
}
class T extends B with A,S{
}
// class T = B with A, S;
main() {
  T t = new T();
  t.a();
  t.b();
  t.c();
  assert(t is S);//mixins的类型就是其超类的子类型,所以都会为ture
}

你可能感兴趣的:(03-Dart语法--对象的构建者以及操控者)