Dart基础3-类

1 构造函数

  1. 不要键入初始化的形式
  2. 空的构造函数体使用;而不是{}
  3. 不要使用new
  4. 不要过多使用const
    上面的说法只是规范性,当然你用了也不影响
class Point {
  num x, y;
  //默认构造函数,只存在一个
  Point(this.x, this.y);
}
void main() { 
  //不要使用new(即使使用并不报错,但并不推荐,因为已经弃用了)
  var p = Point(1,2);
}

1.1 默认构造函数

  1. 默认构造函数只能存在一个
  2. 无返回值
  3. 如类无构造函数,则会自动创建一个隐式的无参默认构造函数
    注意:是无构造函数,并非无默认构造函数
class Point {
  num x, y;
  //无构造函数会创建一个默认的无参构造函数 即Point();
}
void main() {  
  Point p = Point();
}

1.2 命名构造函数

可理解为默认构造函数的重载,可存在多个

class Point {
  num x, y;
  //命名构造函数
  Point.temp(this.x, this.y);
  //:后是赋值
  Point.temp2(a,b): x=a,y=b;
}

void main() {  
  Point p = Point.temp(1, 2);
  Point p2 = Point.temp2(1,2);
  Point p3 = Point();  //错误,无无参默认构造函数
}

1.3 重定向构造函数

重定向构造函数的主体为空,构造函数调用出现在冒号(:)之后

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

  Point.alongXAxis(num x) : this(x, 0);
  
  Point.alongXAxis2() : this.alongXAxis(0);
}

1.4 常量构造函数

生成的对象不会改变,所有的属性都是final的

class ImmutablePoint {
  static final ImmutablePoint origin =const ImmutablePoint(0, 0);
  final num x, y;

  const ImmutablePoint(this.x, this.y);
}

1.5 工厂构造函数

工厂构造函数可以从缓存返回实例,也可以返回子类型的实例

  1. factory修饰上述构造函数 , 修饰后需要返回值,返回本类类型
  2. 内部不能使用this
class Logger {
  final String name;
  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);
}

2 setter和getter

当定义一个属性时,会自动创建隐式的setter和getter方法,当属性被final或const修饰时,只会创建getter方法

class Box {
  num get contents => contents*2;   //错误,会重复回调,get中不能再次使用contents
      set contents(value) {
        contents = value - 1;
      }
      
   num get single => 0;   //只定义get方法,是没有set方法的,效果等同于final(优点在于,在抽象类中,这种属性可以将属性的值延迟定义在子类实现中) 
}
//使用
void main() { 
  var b = Box();
  b.contents;       //调用get方法
  b.contents = 2;   //调用set方法
}

3 继承extends

继承类只能有一个

方法继承

class 继承后方法和属性可重写

abstract class 继承后,其中的抽象方法必须重写(@override

mixin 不可继承


构造函数继承

  1. 继承默认无参构造函数时,可以省略
  2. 重定向继承的构造函数不能有实体
  3. 可随意继承,不必对应
  4. 先调用父类,再调用子类构造函数
class B{
  int x;
  B(this.x){
    print("B $x");
  }
  B.mm(){
    print("B.mm");
  }
}

class T extends  B{
  T(int x): super(x){    //如果super无参数则可以省略
    print("T $x");
  }
  //命名构造函数的继承方式与默认构造函数是一样的
  T.mm(): super(1){
    print("T.mm");
  }
  T.nn(): super.mm(){
      print("T.mm");
  }
  T.aa():this.nn();   //重定向构造函数,不能有实体
}

void main() {
  T t = T(1);  //先打印B 1 ,在打印T 1
}

4 实现implements

  1. 实现的接口可存在多个
  2. dart不存在interface, 上面3类型都可实现
  3. 方法都必须重写实现(不会使用接口的方法)
  4. 属性都必须实现(setter/getter,final只需要getter),向上兼容,且值并不会传递过来
class A{
  void b(){
    print("A.b");
  }
}

abstract class B{
  final int x =1;
  int y = 1;
  void b();
}

class T extends  A implements B{
  //重写x属性,这里扩展了方法setter。
  @override
  int x = 2;   //向上兼容,反之错误
  //final int y = 2;   //错误,将y属性已经存在的setter方法去掉并不合理
  void printX(){
    print("T.x $x"); //打印T.x 2
  }
}

void main() {
  T().b();
}

5 混合with

这个概念,主要是解决无法继承多个父类的问题

但是,引入多个父类的话,会造成方法和属性重复,这时就要靠with决定

//A中的方法和属性为A和S方法的集合,如果有重复,取S中的
class T = A with S;
//多个就顺序混合,即 (A with B)with S
class T2 = A with B,S;
//顺序混合,即 (A with C)with S
class T3 with A,C,S{}

混合是顺序的,类似于贴纸,最后贴的保存使用
关于super
T2中的S内使用super,那么调用的将是A with B内的方法或属性,是层级结构的
注意:用于混合的类不能声明构造函数

class S {
  int x = 1;
  a() {print("S.a");}
  //S();  声明构造函数就不能用于混合
}

class A {
  int x = 2;
  a(){print("A.a");}
  b(){print("A.b");}
}

class B {
  int x = 3;
  a(){print("B.a");}
  b(){print("B.b");}
  c(){print("B.c $x");}  //S在最末,所以x的值去S中的x
}

mixin C{}
//mixin的继承方式使用on(只能一个父类)
mixin C2 on A{}
////mixin的实现方式使用implements(可以多个接口)
mixin C3 on A implements B,S{}

//方式一
class T = B with A, S;
//方式二,可加入新的方法
class T2 extends B with A, S{
    //方法重写,优先级最高
    a(){print("T2.a");}
}
//方式三,可直接混合
class T3 with A,C,S{
    
}

void main() {
  T t = T();
  //打印顺序为:S.a    A.b      B.c 3
  t.a();
  t.b();
  t.c();
}

6 可调用的类

实现call()方法可以让你的Dart类像函数一样被调用

class WannabeFunction {
  call(String a, String b, String c) => '$a $b $c!';
}

main() {
  var wf = new WannabeFunction();
  var out = wf("Hi", "there,", "gang");
  print('$out');
}

7 元数据

元数据即javaannotation注解,但本质是一个常量构造函数

class Todo {
  final String who;
  final String what;

  const Todo(this.who, this.what);
}

@Todo('seth', 'make this do something')
void doSomething() {
  print('do something');
}

元数据可以出现在库、类、类型定义、类型参数、构造函数、工厂、函数、字段、参数或变量声明之前,也可以出现在导入或导出指令之前

元数据可配合反射(mirrors)使用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容