10天学会flutter DAY2 玩转dart 类

print(point.y);

复制代码
*   使用 ?. 代替. 可以避免因为左边表达式为null 而导致的问题 (这个是flutter 2.0 之后新增的空认证功能)

print(point?.x);

print(point?.y);

复制代码
*   如下代码所示`p1.y = 6;` **setter** 写入方法, `print(p1.y);` **getter** 读取方法

p1.y = 6;

print(p1.y);

复制代码
[]( )2、构造函数

--------------------------------------------------------------------



> 可以使用 **构造函数** 来创建一个对象。构造函数的命名方式可以为 `类名` 或 `类名 . 标识符` 的形式。例如下述代码分别使用  

> `Point()` 和 `Point.fromJson()` 两种构造器创建了 `Point` 对象:

class Point {

int? x;

int? y;

Point(this.x, this.y);

Point.fromJson(Map map) {

复制代码
x = map['x'];

y = map['y'];

}

}

复制代码
*   下面两段代码,执行的结果都是获取的对应的**x** 的值

var p1 = Point(2, 3);

print(p1.x);

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

print(p2.x);

复制代码
[]( )3、常量构造函数

----------------------------------------------------------------------



> 实例变量可以是`final`,在这种情况下,它们必须只设置一次。在声明时,使用构造函数形参或构造函数的初始化列表初始化最终的**非延迟实例变量**:

class ProfileMark{

final String name;

final DateTime start = DateTime.now();

ProfileMark(this.name);

ProfileMark.unNamed() : name = '';

}

复制代码
*   一些类提供了**常量构造函数**。使用常量构造函数,在构造函数名之前加 `const` 关键字,来创建编译时常量时:

class ImmutablePoint {

final int? x;

final int? y;

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

}

复制代码
*   下面代码中的 p1 和 p2 的执行结果是true, 它们其实是同一个实例

var p1 = const ImmutablePoint(1, 1);

var p2 = const ImmutablePoint(1, 1);

assert(p1 == p2);

复制代码
*   在 **常量上下文** 场景中,你可以省略掉构造函数或字面量前的 `const` 关键字。例如下面的例子中我们创建了一个常量 Map:

const pointAndLine = const{

复制代码
'point': const[const ImmutablePoint(1, 1)],

'line': const[const ImmutablePoint(1, 10), const ImmutablePoint(1, 11)],

};

复制代码
*   根据上下文,可以只保留一个`const` 关键字,其余的全部省略:

const pointAndLine = {

复制代码
'point': [ImmutablePoint(1, 1)],

'line': [ImmutablePoint(1, 10), ImmutablePoint(1, 11)],

};

复制代码
*   但是如果无法根据上下文判断是否可以省略 `const`,则不能省略掉 `const` 关键字,否则将会创建一个 **非常量对象** 例如:

var p1 = const ImmutablePoint(1, 1);

var p2 = ImmutablePoint(1, 1);

assert(p1 == p2);

复制代码
*   上面代码执行结果会抛出异常:



![在这里插入图片描述](https://img-blog.csdnimg.cn/146143e1359f434b835a589d03ae5bdf.png)



[]( )4、默认构造函数

----------------------------------------------------------------------



> 如果你没有声明构造函数,那么 Dart 会自动生成一个无参数的 构造函数并且该构造函数会调用其父类的 无参数构造方法。



[]( )5、构造函数不被继承

------------------------------------------------------------------------



> 子类不会继承父类的构造函数,如果子类没有声明构造函数,那么只会有一个默认无参数的构造函数。



[]( )6、命名式构造函数

-----------------------------------------------------------------------



> 可以为一个类声明多个命名式构造函数来表达更明确的意图:

class Point {

final int? x; // int? 可空类型

final int? y;

Point(this.x, this.y);

// 命名构造函数,上面讲过

: x = xOrigin,

复制代码
y = yOrigin;

}

复制代码
> 记住构造函数是不能被继承的,这将意味着子类不能继承父类的命名式构造函数,如果你想在子类中提供一个与父类命名构造函数名字一样的命名构造函数,则需要在子类中显式地声明。



[]( )7、调用父类非默认构造函数

---------------------------------------------------------------------------



> 默认情况下,子类的构造函数会调用父类的匿名无参数构造方法,并且该调用会在子类构造函数的函数体代码执行前,如果子类构造函数还有一个  

> 初始化列表,那么该初始化列表会在调用父类的该构造函数之前被执行,总的来说,这三者的调用顺序如下:



1.  初始化列表

2.  父类的无参数构造函数

3.  当前类的构造函数



如果父类没有匿名无参数构造函数,那么子类必须调用父类的其中一个构造函数,为子类的构造函数指定一个父类的构造函数只需在构造函数体前使用(:)指定。



下面的示例中,Employee 类的构造函数调用了父类 Person 的命名构造函数。

class Person{

String? firstName;

Person.formJson(Map map){

复制代码
print("进入了Person 的命名函数中、、、");

}

}

class Employee extends Person{

// Person没有默认构造函数;

//你必须重新Employee.formJson 并调用 super.fromJson(data)。

Employee.formJson(Map map) : super.formJson(map){

复制代码
print("进入了 Employee 子类");

}

}

main{

var employee = Employee.formJson({});

print(employee);

}

复制代码
上面实例代码打印如下:



![在这里插入图片描述](https://img-blog.csdnimg.cn/4365dd3e03d149f9840c9c09bb57dcfc.png)



因为参数会在子类构造函数被执行前传递给父类的构造函数,因此该参数也可以是一个表达式,比如一个函数:

class Employee extends Person {

Employee() : super.fromJson(fetchDefaultData());

// ···

}

复制代码
[]( )8、获取对象的类型

-----------------------------------------------------------------------



> 可以使用 `Object` 对象的 `runtimeType` 属性在运行时获取一个对象的类型,该对象类型是 Type 的实例。

print('p1 的实例类型是 ${p1.runtimeType}');

复制代码
[]( )9、初始化列表

---------------------------------------------------------------------



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

class Point {

final int? x; // int? 可空类型

final int? y;

: x = map['x'],

复制代码
y = map\['y'\] {

print('In Point.fromJson(): ($x, $y)');

}

}

复制代码
*   代码调用

Point.fromJson({'x': 2, 'y': 3});

复制代码
*   运行结果如下:



![在这里插入图片描述](https://img-blog.csdnimg.cn/10cd3a2ce65e44e9b8175c83d404c6a3.png)



*   在开发模式下,你可以在初始化列表中使用 assert 来验证输入数据:

Point.withAssert(this.x, this.y) : assert(x! > y!){

复制代码
print('In Point.withAssert(): ($x, $y)');

}

复制代码
上面代码中,如果 `assert(x! > y!)` 不为true,会直接抛出异常



*   使用初始化列表设置 `final` 字段非常方便,下面的示例中就使用初始化列表来设置了三个 `final` 变量的值。

class Point {

final double? x; // int? 可空类型

final double? y;

final double distanceFromOrigin;

: x = x,

复制代码
y = y,

distanceFromOrigin = (x \* x + y \* y);

}

main{

var p = Point(2, 5);

print(p.distanceFromOrigin);

}

复制代码
运行结果为:



![在这里插入图片描述](https://img-blog.csdnimg.cn/3514bd19b56b49cdba4470d8e41b2b4b.png)



[]( )10、重定向构造函数

------------------------------------------------------------------------



> 有时候类中的构造函数仅用于调用类中其它的构造函数,此时该构造函数没有函数体,只需在函数签名后使用(:)指定需要重定向到的其它构造函数 (使用  

> `this` 而非类名):

class Point{

double x, y;

// this 主构造函数

Point(this.x, this.y);

Point.alongXAxis(double x): this(x, 0);

}

main{

var p = Point(2, 5);

print(p.y);

print(p.x);

var p1 = Point.alongXAxis(10);

print(p1.y);

print(p1.x);

}

复制代码
运行结果如下:



![在这里插入图片描述](https://img-blog.csdnimg.cn/40381dba452248a7900d3e7db8f32f45.png)



[]( )11、工厂构造函数

-----------------------------------------------------------------------



> 使用 `factory`  

> 关键字标识类的构造函数将会令该构造函数变为工厂构造函数,这将意味着使用该构造函数构造类的实例时并非总是会返回新的实例对象。例如,工厂构造函数可能会从缓存中返回一个实例,或者返回一个子类型的实例。



*   在如下的示例中, `Logger` 的工厂构造函数从缓存中返回对象,和 `Logger.fromJson` 工厂构造函数从 JSON 对象中初始化一个最终变量。

class Logger{

final String name;

// 带有 _cache 表示是私有的

static final Map<String, Logger> _cache = <String, Logger>{};

factory Logger(String name){

复制代码
return _cache.putIfAbsent(name, () => Logger._internal(name));

}

相关推荐
张风捷特烈3 小时前
Flutter 伪3D绘制#03 | 轴测投影原理分析
android·flutter·canvas
马拉萨的春天6 小时前
flutter 项目结构目录以及pubspec.ymal等文件描述
flutter
omegayy6 小时前
Unity 2022.3.x部分Android设备播放视频黑屏问题
android·unity·视频播放·黑屏
mingqian_chu6 小时前
ubuntu中使用安卓模拟器
android·linux·ubuntu
自动花钱机6 小时前
Kotlin问题汇总
android·开发语言·kotlin
行墨9 小时前
Kotlin 主构造函数
android
前行的小黑炭9 小时前
Android从传统的XML转到Compose的变化:mutableStateOf、MutableStateFlow;有的使用by有的使用by remember
android·kotlin
_一条咸鱼_9 小时前
Android Compose 框架尺寸与密度深入剖析(五十五)
android
在狂风暴雨中奔跑9 小时前
使用AI开发Android界面
android·人工智能
行墨9 小时前
Kotlin 定义类与field关键
android