Dart中的构造函数有4种,分别是:

  • ClassName(...) //普通构造函数
  • Classname.identifier(...) //命名构造函数
  • const ClassName(...) //常量构造函数
  • factroy ClassName(...) //工厂构造函数

普通构造函数

普通构造函数可以分为无参构造函数和有参构造函数。

如果不声明构造函数,则dart会提供一个默认的无参构造函数。当然,也可以自己定义有参构造函数,如果自己写了构造函数,那么默认构造函数就不存在了。

我们可以这么来定义一个有参构造函数

class People{int? age;String? name;People(int age, String name){this.age = age;this.name = name;}
}

这种赋值方式如果变量很多的话写起来比较麻烦,所以dart提供了语法糖来简化,直接在参数列表上这么写:

class People{int? age;String? name;People(this.age, this.name);
}

注意:

  • Dart 构造函数不允许重载,即不允许有相同名称的构造函数,否则编译器会报错

如果想设置不同的参数可通过可选参数列表来设置:

class People{int? age;String? name;People({this.age, this.name});
}

这种写法涵盖了这么几种形式:

People();
People(this.age);
People(this.name);
People(int age, String name);
  • 当子类继承父类时,初始化子类构造函数会优先初始化父类构造函数,继承时需要使用 super调用父类构造函数,若父类为无参构造函数时可以省略。
class Child extends People{Child(int age, String name): super(age: age, name: name);// Child(int age, String name); 若父类为无参构造函数时则可以省略super调用
}

命名构造函数

格式:类名.构造函数名

class People{int? age;String? name;People.fromMap(Map map){this.age = map["age"];this.name = map["name"];}
}

使用命名构造函数可为一个类实现多个构造函数,但是同样是不能重载。

如果一个里只有命名构造函数,那么子类需要显示调用父类的命名构造函数。

class B extends People{B(Map map) : super.fromJson(map);
}

否则会报错


初始化列表

除了调用父类的构造函数,你还可以在执行构造函数体及调用父类构造函数之前初始化实例变量,使用逗号分隔每个初始化变量。

class Employee extends People {int? no;String? job;String? address;int? age1;Employee(this.job, this.address, int? age): this.no = 123456,age1 = age ?? 25,super(age: age);
}

调用的顺序如下:

  • 初始化列表
  • 父类的构造函数
  • 子类的构造函数

参数列表对于初始化那些final修饰的成员变量很有用,因为在方法体中,不能给final修饰的成员变量赋值,因为在执行方法体的时候,final修饰的成员变量已经不能变了。

注意:

  • 传递给父类构造函数的参数及初始化表达式的右边不能使用 this 关键字和访问实例成员变量,因为在参数传递的这一步骤,子类构造函数尚未执行,子类的实例对象也就还未初始化,因此所有的实例成员都不能被访问。
  • 同一实例成员在参数列表和初始化列表中不能同时存在,

构造函数传递(重定向构造函数)

定义构造函数的时候,除了可以定义一个普通构造函数之外,还可以定义若干个命名构造函数,这些构造函数之间,有时候会有一些相同的逻辑,如果分别写在各个构造函数中,会显得有些多余,所以构造函数可以传递。传递构造函数是没有方法体的,可以在初始化列表中,调用另一个构造函数。

class Point {final num x;final num y;final num area;Point(x, y): this.x = x,this.y = y,this.area = x * x + y * y;Point.alongXAxis(num x) : this(x, 0);
}

如果添加方法体,编译器会报错。


常量构造函数

如果生成类的对象是不会变的,可以定义常量构造函数(如果你的类,创建的对象永远不会改变,你可以在编译期就创建这个常量实例,并且定义一个常量构造函数,并且确保所有的成员变量都是final的。)。

class Point {final num x;final num y;final num area;const Point(x, y): this.x = x,this.y = y,this.area = x * x + y * y;
}

在使用时需注意:

  1. 常量构造函数必须用 const 关键词修饰;比如我们定义一个常量,给该常量赋的值必须也是常量。(使用const赋值声明,后面的const可省略)。
  2. 所有实例变量必须是 final 类型的。
  3. 常量构造函数不允许有函数体。
  4. 实例化时需要加 const, 否则实例化的对象仍然可以修改变量值。

工厂构造函数

有时候可能有一种需求,并不需要每次都创建新的类实例,而是每一种情况,只需要一个实例,这时候工厂构造函数就派上用场了。

工厂构造函数使用关键字factory来定义,factory可以放在类名函数之前,也可以放在命名函数之前。

使用场景:

  1. 避免创建过多的重复实例,如果已创建该实例,则从缓存中拿出来。

    class Logger {final String name;bool mute = false;// _cache 变量是库私有的,因为在其名字前面有下划线。static final Map<String, Logger> _cache =<String, Logger>{};factory Logger(String name) {return _cache.putIfAbsent(name, () => Logger._internal(name)); //工厂构造函数里可以调用其他构造函数。}factory Logger.fromJson(Map<String, Object> json) {return Logger(json['name'].toString());}Logger._internal(this.name);void log(String msg) {if (!mute) print(msg);}
    }
  2. 实现简单工厂模式,在java中抽象类是不能直接被实例化的,但是在dart中,使用工厂构造函数可以让抽象类被实例化。
    abstract class Animal {String? name;void getNoise();factory Animal(String type, String name) {switch (type) {case "cat":return new Cat(name);case "dog":return new Dog(name);default:throw "The '$type' is not an animal";}}
    }class Cat implements Animal {String? name;Cat(this.name);@overridevoid getNoise() {print("${this.name}: 喵~");}
    }class Dog implements Animal {String? name;Dog(this.name);@overridevoid getNoise() {print("${this.name}: 旺~");}
    }
    void main() {var cat = new Animal("cat", "花花");var dog = new Animal("dog", "小黑");cat.getNoise(); // 花花:  喵~dog.getNoise(); // 小黑: 旺~
    }
  3. 单例模式,可用于工具类。
    class Singleton {static final Singleton _singleton = Singleton._internal();factory Singleton() {return _singleton;}Singleton._internal();
    }
    void main() {var s1 = Singleton();var s2 = Singleton();print(identical(s1, s2)); // true
    }

注意:

  1. 工厂构造函数不能和其他构造函数一样,使用this关键字来调用class的属性和方法。工厂构造函数只能使用类中static类型的属性和方法。
  2. 在其他类型的构造函数方法体里是不能有返回值,也就是不能出现return关键字,但是工厂函数是必须要有的,而且不能返回null。

Dart中的构造函数相关推荐

  1. Dart中常量构造函数

    class Container {final int width;//常量构建函数的变量必须使用final关键字进行修饰final int height;const Container({requir ...

  2. dart系列之:dart类中的构造函数

    文章目录 简介 传统的构造函数 命名构造函数 构造函数的执行顺序 重定向构造函数 Constant构造函数 工厂构造函数 总结 简介 dart作为一种面向对象的语言,class是必不可少的.dart中 ...

  3. dart系列之:时间你慢点走,我要在dart中抓住你

    文章目录 简介 DateTime Duration 总结 简介 时间和日期是我们经常会在程序中使用到的对象.但是对时间和日期的处理因为有不同时区的原因,所以一直以来都不是很好用.就像在java中,为时 ...

  4. 懂集合吗?对,是dart中的集合

    文章目录 简介 List的使用 Set的使用 Map的使用 常见的集合方法 总结 简介 dart中的集合有三个,分别是list,set和map.dart在dart:core包中提供了对于这三种集合非常 ...

  5. Dart中的mixins

    /* mixins的中文意思是混入,就是在类中混入其他功能.在Dart中可以使用mixins实现类似多继承的功能,with关键字因为mixins使用的条件,随着Dart版本一直在变,这里讲的是Dart ...

  6. Dart中抽象类 多态以及接口

    Dart中抽象类:Drat抽象类主要是用于定义标准,子类可以继承抽象类,也可以实现抽象类接口. 1.抽象类通过abstract关键字来定义 2.Drat中的抽象方法不能用abstract声明,Dart ...

  7. 深入理解 Dart 中的继承和 Minxins

    上一篇文章中我们详细地介绍了 Dart 中的面向对象的基础,这一篇文章中我们继续探索 Dart 中面向对象的重点和难点(继承和 Mixins).Mixins(混合)特性是很多语言中都是没有的.这篇文章 ...

  8. php中的构造函数和析构函数,php 中构造函数和析构函数

    构造函数: 在对象实例化时被调用,一个类中只能有一个构造函数,在类中起初始化的作用. 析构函数: 在对象结束时被自动调用. 话不多说,用一段代码来说明两者的区别: //定义一个类 class Pers ...

  9. getvalue函数怎么使用_Java中的构造函数——通过示例学习Java编程(14)

    作者:CHAITANYA SINGH 来源:通过示例学习Java编程(14):Java中的构造函数-方家话题 构造函数是用来初始化新创建的对象的代码块.构造函数类似于java中的实例方法(Instan ...

  10. Java中的构造函数和重载

    一.Java中的构造函数 构造函数是对象被创建时初始化对象的成员方法,它具有和它所在的类完全一样的名字.构造函数只能有入口参数,没有返回类型,因为一个类的构造方法的返回类就是类本身.构造函数定义后,创 ...

最新文章

  1. LastPass 释出安全更新修复高危漏洞
  2. 关于在本地idea当中提交spark代码到远程的错误总结(第二篇)
  3. SQL Server扩展事件(Extended Events)-- 将现有 SQL 跟踪脚本转换为扩展事件会话
  4. .Net Micro Framework研究—实现SideShow窗体界面
  5. BZOJ3343 教主的魔法 二分法+分块
  6. 安卓系统使用chrome插件(以yandex安装油猴为例)
  7. 【039】读典籍-在线阅读典籍并对应翻译
  8. markdown语法的使用
  9. 事件clientX、pageX、screenX、offsetX
  10. Domain Adaptive在无监督语义分割上的应用
  11. Emmagee—开源Android性能测试工具
  12. Java各种运算符号的含义及区别汇总
  13. 国防科大计算机学院暑期学校,国防科技大学研究生暑期学校:夏季学期别样红...
  14. 下载自媒体内容素材,帮你快速创造内容
  15. 什么是服务端与客户端详解
  16. 小米5无线显示如何连接到服务器,小米电视无线显示怎么用?详细操作方法
  17. excel不显示0_单元格为0不显示的几种方法
  18. 数据泄漏检测和溯源技术
  19. android手写汉字,Android 手写输入的实现(保存涂鸦文字)
  20. 王汕7.10期货原油、外汇黄金指导、黄金走势分析及下周操作建议

热门文章

  1. http代表的是什么?http代表的是什么意思
  2. Pina Colada Song现实版
  3. 个人所得税计算java版
  4. VML标记与通用属性
  5. 谷歌统计 Google Analytics使用gtag.js 进行数据统计(VUE)
  6. Shader特效之图片波动炫光效果
  7. 万王之王手游服务器维护,万王之王手游-KOK-官方网站-腾讯游戏-一个世界的重新开启...
  8. 在线Java/C++/C语言/Python/web网页编辑器(IDE)整理
  9. mmdetection - config配置文件之schedule(learning rate)
  10. 如何在Github上建立自己的个人博客网站详细教程