前言:楼主平时基本没有使用过异常处理,所以对异常的认知可能不够准确,这里就不翻译异常的相关内容了,大家可以去官网自行阅读介绍,地址 https://dart.dev/guides/language/language-tour#exceptions

我们前面提到,dart是面向对象的语言,程序中的每个对象都可以看作是某个类的实例。所有的类都派生自Object类。

(一)使用类的成员

与C++等面向对象语言一样,dart的类成员包括方法(接口)与数据,使用点号操作符(.)可以访问类的方法和数据。看个简单例子:

//实例化Point类的一个对象,命名为p
var p = Point(, ); // 设置类的成员y的值.
p.y = ; // 获取成员y的值
assert(p.y == ); // 调用类的distanceTo方法
num distance = p.distanceTo(Point(, ));

一个小技巧: 使用 ?. 可以避免访问一个空实例,如下例:

// If p is non-null, set its y value to 4.
p?.y = ;

(二)构造器

了解C++的朋友都知道,在C++中类一定有构造函数,dart也是如此。

在dart中使用构造器创建一个对象,构造器可以是ClassName or ClassName.identifier,看以下例子:

// 使用 ClassName 创建
var p1 = Point(, );
// 使用 ClassName.identifier 创建
var p2 = Point.fromJson({'x': , 'y': });

也可以使用 new 关键字创建,如下:

var p1 = new Point(, );
var p2 = new Point.fromJson({'x': , 'y': });

以上两段代码的效果是一样的。

(题外话:在C++中使用new创建的是指针,在这里我们看到,以上两段代码返回都是var类型)

可以使用const关键字创建编译时常量的对象,简单例子:

var a = const ImmutablePoint(, );
var b = const ImmutablePoint(, ); assert(identical(a, b)); // They are the same instance!

接着再看如下例子:

var a = const ImmutablePoint(, ); // Creates a constant
var b = ImmutablePoint(, ); // Does NOT create a constant assert(!identical(a, b)); // NOT the same instance!

通过以上两段代码我们可以看出:即便构造器调用参数完全相同,const和非const对象也是不等同的。

(三)获取一个对象的类型

可以调用对象的 runtimeType 属性获取对象的运行时数据类型, 该属性是 Type 类型的对象。

print('The type of a is ${a.runtimeType}');

(四)实例变量

先看一个例子:

class Point {
num x; // 声明实例变量x
num y = ; // 声明实例变量y
}
void main()
{
var p = Point(); // 构造Point类的实例p
print("y = ${p.y}");
if(p.x == null)
{
print("p.x == null");
}
else
{
print("eeee");
}
}

代码运行结果

通过上例我们可以看出:类中的变量默认被初始化为null,如果我们在类声明时对变量进行了初始化(如Point类中的y),则该初始化赋值发生在调用构造函数之前

(五)构造函数

我们可以通过声明一个与类名完全相同的函数来声明构造函数(和C++一样),当然,也可以选择附加标识符,如 (二)构造器 一段所述。看个例子:

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

这里的this关键字指当前实例自身,另注:只在名字有冲突的时候才适用this关键字,否则可以省略。

(1)默认构造函数

前面已经提到,和C++一样,如果你没有声明自己的构造函数,那么编译器会给你提供一个默认的构造函数,默认构造函数无入参,并且调用父类的无参构造函数。

(2)构造函数不能继承

子类不能继承父类的构造函数。前面提到,子类如果没有声明构造函数,那么会有默认的构造函数,而不是集成父类的。

(3) 命名构造函数 (Named constructor)

看个例子:

class Point {
num x, y; Point(this.x, this.y); // Named constructor
Point.origin() {
x = ;
y = ;
}
}

记住,构造函数不能继承!如果想用父类中的命名构造函数创建一个子类,那你也必须在子类中实现这个命名构造函数!

(4) 构造函数的调用顺序

子类的构造函数中执行的操作顺序如下:

初始化列表->父类的无参构造函数->本类的无参构造函数。

如果父类没有非命名、无参数的构造函数,那么你就必须手动调用父类的一个构造函数,在分号(:)后指明调用的父类构造函数,看以下例子:

class Person {
String firstName; Person.fromJson(Map data) {
print('in Person Class');
}
} 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 Class');
}
} main() {
var emp = new Employee.fromJson({}); // Prints:
// in Person Class
// in Employee Class
if (emp is Person) {
// Type check
emp.firstName = 'Bob';
print("emp is Person, firstname = ${emp.firstName}");
}
(emp as Person).firstName = 'Bob';
print("Other,firstname = ${emp.firstName}");
}

以上代码在vs code中运行结果如下:

父类构造函数的参数中无权限使用this关键字!

(5) 重定向构造函数

这个重定向构造函数,个人理解有一点点像C++里虚基的构造函数,重定向构造函数函数体为空,仅仅是在该类里用来重定向其他的构造函数的。看一个例子:

class Point {
num x, y; // Point类的主构造函数,也是一个重定向构造函数,你看它的函数体是空的
Point(this.x, this.y); // alongXAxis函数被重定向到Point执行构造处理
Point.alongXAxis(num x) : this(x, );
}

(6)其他

官方对于构造函数还有一些其他类型的描述,如constant构造、factory构造等,本人对此不甚理解,因此这里就不做翻译,大家有兴趣请去官网阅读相关说明。

[dart学习]第七篇:类(构造函数)的更多相关文章

  1. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

  2. c++学习之对象和类——构造函数和析构函数

    再认真理一遍~ 0.类 这里先来定义一个类,便于后面的理解.参考C++ Primer Plus class Stock { private: std::string company; long sha ...

  3. [dart学习]第三篇:dart变量介绍 (二)

    本篇继续介绍dart变量类型,可参考前文:第二篇:dart变量介绍 (一) (一)final和const类型 如果你不打算修改一个变量的值,那么就把它定义为final或const类型.其中:final ...

  4. [dart学习]第五篇:操作符

    前言:本系列内容假设读者有一定的编程基础,如了解C语言.python等. 本节一起来学习dart的操作符,直接拷贝官网的操作符描述表如下: Description Operator unary pos ...

  5. 从.Net到Java学习第七篇——SpringBoot Redis 缓存穿透

    从.Net到Java学习系列目录 场景描述:我们在项目中使用缓存通常都是先检查缓存中是否存在,如果存在直接返回缓存内容,如果不存在就直接查询数据库然后再缓存查询结果返回.这个时候如果我们查询的某一个数 ...

  6. [dart学习]第四篇:函数和操作符(本篇未完待续)

    接着学习dart的函数和操作符. 1.函数Function dart是一种真正的面向对象的语言,通常一个函数也是Function类型的对象,这也就是说可以把函数赋值给一个变量,或者作为另一个函数的入参 ...

  7. [dart学习]第六篇:流程控制语句

    经过前面的基础知识了解学习,我们今天可以进入语句模块啦. dart主要有以下流程控制语句: if-else for循环 while和do-while循环 break和continue switch-c ...

  8. Java学习第七篇:与运行环境交互

    目录 一.与用户互动 1.main方法形参 2.使用Scanner类获取输入 3.使用BufferedReader类获取输入 二.常用类 1.System类和Runtime类 2.String, St ...

  9. Java学习第三篇:类的三大特征,抽象类,接口,final关键字

    一.类的三大特征 1.封装性 (1).什么是封装 封装就是把抽象出的数据和对数据的操作封装在一起, 数据被保护在内部, 程序的其他部分只有通过被授权的操作(成员方法), 才能对数据进行操作. (2). ...

随机推荐

  1. 配置tmux在机器重启后自动恢复tmux工作现场,告别重启恐惧症

    1. 问题出现的背景 通过ssh远程登录服务器在上面工作,有时候很有可能由于网络断开而导致ssh链接断开,或者下班后想继续在家登录到服务器继续工作.这些情况都需要服务器保持我们的工作环境,比如,vim ...

  2. Disable trigger to avoid the ID is auto-updated

    CREATE TABLE COBRA.COBRA_PRODUCT_INFO_BAK AS SELECT * FROM COBRA.COBRA_PRODUCT_INFO; TRUNCATE TABLE ...

  3. mongodb的基本操作之数据删除

    删除操作使用remove进行,数据的删除与查询类似,接受一个参数,与查询不同的是,为了防止误操作,删除操作不允许不传参数 比如 db.test_collection.remove() 会报错 Erro ...

  4. 剑指Offer的学习笔记(C#篇)-- 孩子们的游戏(圆圈中最后剩下的数)

    题目描述 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随机指 ...

  5. [唐胡璐]Selenium技巧 - 定制元素属性检查,并写到ReportNG中

    QTP 和Selenium 都会有这种要检查某一个控件元素属性的情况,比如去检查一个Button的显示文字是什么? 为了更方便的书写程序,并优美的显示到HTML测试报告中,做了以下几个小小的封装,只是 ...

  6. C#串口图片传输以及对串口缓冲区的简单理解

    第一次接触串口,写点东西加深自己对串口的印象: 通过参考一些网上的实例,我明白了串口怎么简单的进行通信交流,但是我所需要的还是图片等大文件在串口中的传输,串口传输是通过二进制位进行单位传输的,所以传输 ...

  7. Ellipsis对象

    Ellipsis对象. 写作 : ‘…’ 中文解释:省略 该对象bool测试是为真 用途: 1.用来省略代码,作用类似于pass的一种替代方案,这是python的’TBD’(未确定内容). def f ...

  8. 题解 [JOI 2019 Final] 独特的城市

    题面 解析 首先有一个结论, 对一个点\(x\)有贡献的城市 肯定在它到离它较远的直径的端点的链上. 假设离它较远的端点是\(S\), 如果有一个点\(u\)不在\(x\)到\(S\)的链上, 却对\ ...

  9. 基于Kinect 2.0深度摄像头的三维重建

    刚今天验收的实验,记录一下. 是比较基础的三维重建内容. 算是三维重建入门. 系统:windows 环境:visual studio 2013 语言:c++ 相关:OpenCV 2.Kinect SD ...

  10. 指针&虚函数多态性

    class Class1 { public: virtual void f() { cout << "Function f() in Class1 \n"; } voi ...