Flutter/Dart第14天:Dart类详解
Dart官方文档:https://dart.dev/language/classes
重要阐明:本博客依据Dart官网文档,但并不是简略的对官网进行翻译,在掩盖中心功用状况下,我会依据个人研制经历,参加自己的一些扩展问题和场景验证。
Dart类
Dart言语依据类和Mixin承继,是一门面向目标言语。任何目标都是某个类的实例,除Null
之外,Object
类其他一切类的父类。
Mixin承继:Dart言语和Java言语相同,类只能是单承继。但经过Mixin,一个类的代码能够在多个类层次结构中复用(有关Minxin的具体阐明见之前文章:https://ntopic.cn/p/2023093001)。
办法扩展:在不改动原有类和添加子类的状况之下,经过Dart的办法扩展,能够给类添加功用的一种办法(这个特性在Flutter发布的库特别有用)。
类润饰符:能够让咱们可操控一个库假如界说子类。
类成员(办法和变量)
目标是由函数和数据组成,别离代码办法和变量。咱们经过目标.办法
或许目标.变量
的办法来拜访目标办法和变量。当目标可能为null
时,经过目标.?
拜访办法和变量的办法可防止反常产生。
// 界说目标
var p = Point(2, 2);
// 获取目标变量`y`
assert(p.y == 2);
// 调用目标办法:`distanceTo()`
double distance = p.distanceTo(Point(4, 4));
// 当目标`p`非空时,`a`值为变量`y`;不然`a`值为null
var a = p?.y;
类结构函数
在前面学习中,咱们对结构函数有开始知道:https://ntopic.cn/p/2023092401
如下代码样例,能够经过主结构函数和命名结构函数创立一个目标;结构函数之前,咱们也能够添加可选的new
关键字:
var p1 = Point(2, 2);
var p2 = Point.fromJson({'x': 1, 'y': 2});
// 同上等价代码,可选的`new`关键字
var p1 = new Point(2, 2);
var p2 = new Point.fromJson({'x': 1, 'y': 2});
当类的变量都用final
不行变润饰时,咱们能够结构常量目标:
var a = const ImmutablePoint(1, 1);
var b = const ImmutablePoint(1, 1);
// 目标`a`和`b`持平
assert(identical(a, b));
关于一个常量上下文,咱们能够去掉结构函数之前的const
关键字。如下代码样例,咱们界说的是一个常量Map(上下文),那么Map元素的结构器就能够省掉const
关键字:
const pointAndLine = const {
'point': const [const ImmutablePoint(0, 0)],
'line': const [const ImmutablePoint(1, 10), const ImmutablePoint(-2, 11)],
};
// 同上等价代码,可省掉`const`关键字
const pointAndLine = {
'point': [ImmutablePoint(0, 0)],
'line': [ImmutablePoint(1, 10), ImmutablePoint(-2, 11)],
};
假如一个目标没有常量上下文,且没有运用const
润饰结构器,那么它创立的是一个非常量目标:
var a = const ImmutablePoint(1, 1);
var b = ImmutablePoint(1, 1);
// `a`是常量目标,`b`不是常量目标,因而它们不持平!
assert(!identical(a, b));
获取目标类型
经过目标.runtimeType
特点,回来目标的Type
目标。一般状况下,咱们经过目标 is Type
的办法,检测某个目标是否归于某个类型,而不是运用目标.runtimeType == Type
比较办法:
print('The type of a is ${a.runtimeType}');
var a = 'Hello NTopicCN';
assert(a.runtimeType == String);
assert(a is String);
实例变量
如下代码界说样例,声明实例变量,实例变量的默认值为null
:
class Point {
double? x; // 默认值:null
double? y; // 默认值:null
double z = 0; // 默认值:0
}
一切的实例变量都隐含有一个getter
办法,包括final润饰的变量、未运用final润饰的变量、late final润饰的变量(赋值和未赋值)等,都有getter办法。
如下代码样例,几种实例变量润饰和拜访的办法:
class Point {
double? x;
double? y;
}
void main() {
var point = Point();
point.x = 4; // `setter`办法赋值
assert(point.x == 4); // `getter`办法取值
assert(point.y == null); // 默认值为`null`
}
class ProfileMark {
final String name;
final DateTime start = DateTime.now();
// 主结构函数
ProfileMark(this.name);
// 命名结构函数,一起`name`设置初始值
ProfileMark.unnamed() : name = '';
}
隐性接口
在Dart中,每个类都隐含的界说了一个接口,这个接口包括了该类的一切实例成员和该类完成的一切的其他接口。
假定咱们界说了一个类A,它需求支撑类B的API(结构函数不是API),可是类A的界说并不是承继类B,那么类A需求完成B接口。
// `Person`类,也是`Persion`接口,包括`greet()`办法
class Person {
// 归于接口的一部分,可是对外不行见
final String _name;
// 结构函数,不归于接口一部分
Person(this._name);
// 一般办法,归于接口一部分
String greet(String who) => 'Hello, $who. I am $_name.';
}
// 完成`Person`接口
class Impostor implements Person {
String get _name => '';
String greet(String who) => 'Hi $who. Do you know who I am?';
}
String greetBob(Person person) => person.greet('Bob');
void main() {
print(greetBob(Person('Kathy'))); // Hello, Bob. I am Kathy.
print(greetBob(Impostor())); // Hi Bob. Do you know who I am?
}
类变量和办法
static
关键字,能够界说类变量和办法(Java中成为静态变量和静态办法)。
如下代码样例,界说和运用一个类变量:
class Queue {
static const initialCapacity = 16;
// ···
}
void main() {
assert(Queue.initialCapacity == 16);
}
如下代码样例,界说和运用类办法:
import 'dart:math';
class Point {
double x, y;
Point(this.x, this.y);
static double distanceBetween(Point a, Point b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
}
void main() {
var a = Point(2, 2);
var b = Point(4, 4);
var distance = Point.distanceBetween(a, b);
assert(2.8 < distance && distance < 2.9);
print(distance);
}
最佳实践:关于一些常用的东西办法,主张运用尖端办法替代类变量。
类办法能够用作编译期常量,比方:咱们能够把一个类办法当作参数传递给常量结构器。
我的本博客原地址:https://ntopic.cn/p/2023102001