第127期:Dart基础知识(类)

1,158 阅读4分钟

封面图

本文正在参加「金石计划 . 瓜分6万现金大奖」

lADPJxf-zYAK1XnNAtDNBQA_1280_720.jpg

尝试拉片,简单试用了一个剪视频的工具。

Class 类

Dart是一种面向对象的语言,具有类和基于mixin的继承。每个对象都是一个类的实例,除了Null以外的所有类都是从object派生出来的。基于Mixin的继承意味着尽管每个类(除了顶级类Object)只有一个超类,一个类体可以在多个类层次结构中重用。扩展方法是一种在不更改类或创建子类的情况下向类添加功能的方法。

使用类的成员

对象具有由函数和数据(分别为方法和实例变量)组成的成员。

当我们调用一个方法时,我们其实是在一个对象上调用它:该方法可以访问该对象的函数和数据。

这种情况在JS中表现为:当我们直接调用某个方法时,我们其实是在window对象下执行该函数。

var p = Point(2, 2);

// Get the value of y.
assert(p.y == 2);

// Invoke distanceTo() on p.
double distance = p.distanceTo(Point(4, 4));

Dart中也使用.来获取对象方法或属性的引用。

使用?.可以避免该属性为NULL时代码报错。

// If p is non-null, set a variable equal to its y value.
var a = p?.y;

构造函数

我们可以用构造函数创建对象。构造器的名称可以是构造器名,也可以使用构造器的标识符方法,比如:

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});

有些类提供常量构造函数。使用常量构造函数创建编译时常量,需要将const关键字放在构造函数名称之前:

var p = const ImmutablePoint(2, 2);

构造两个相同的编译时常数会导致一个规范实例:

var a = const ImmutablePoint(1, 1);
var b = const ImmutablePoint(1, 1);

assert(identical(a, b)); // They are the same instance!

这两个是同一个实例。

在常量上下文中,可以省略构造函数或文本之前的常量。例如,看看这段代码,它创建了一个常量映射:

// Lots of const keywords here.
const pointAndLine = const {
  'point': const [const ImmutablePoint(0, 0)],
  'line': const [const ImmutablePoint(1, 10), const ImmutablePoint(-2, 11)],
};

如果常量构造函数在常量上下文之外,并且在没有常量的情况下调用,它将创建一个非常量对象:

var a = const ImmutablePoint(1, 1); // Creates a constant
var b = ImmutablePoint(1, 1); // Does NOT create a constant

assert(!identical(a, b)); // NOT the same instance!

获取对象的类型

在运行时获取对象的类型,可以使用object的runtimeType属性,该属性返回一个类型对象。

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

到此为止,上面说的是如何使用一个class, 接下来开始讲怎么样去扩展一个class。

Instance variables 实例变量

声明变量

class Point {
  double? x; // Declare instance variable x, initially null.
  double? y; // Declare y, initially null.
  double z = 0; // Declare z, initially 0.
}

所有未初始化的变量默认值为NULL

所有实例变量都生成隐式getter方法。

非最终实例变量和没有初始值设定项的后期最终实例变量也会生成隐式setter方法

如果在声明的位置初始化非延迟实例变量,则在创建实例时即构造函数及其初始值设定项列表执行之前设置该值。

class Point {
  double? x; // Declare instance variable x, initially null.
  double? y; // Declare y, initially null.
}

void main() {
  var point = Point();
  point.x = 4; // Use the setter method for x.
  assert(point.x == 4); // Use the getter method for x.
  assert(point.y == null); // Values default to null.
}

实例变量可以是final变量,一旦该变量被设定,就不可以再改变该变量的值,通常,由final定义的变量为常量。

class ProfileMark {
  final String name;
  final DateTime start = DateTime.now();

  ProfileMark(this.name);
  ProfileMark.unnamed() : name = '';
}

构造函数

通过创建与其类同名的函数(可选地,还可以使用命名构造函数中描述的附加标识符)来声明构造函数。

class Point {
  double x = 0;
  double y = 0;

  Point(double x, double y) {
    // See initializing formal parameters for a better way
    // to initialize instance variables.
    this.x = x;
    this.y = y;
  }
}

关键字this指向当前实例的引用。

初始化形参

将构造函数参数分配给实例变量的模式非常常见,Dart通过初始化形式参数使其变得简单。

初始化参数也可以用于初始化不可为空的或最终的实例变量,这两个变量都必须初始化或提供默认值。

class Point {
  final double x;
  final double y;

  // Sets the x and y instance variables
  // before the constructor body runs.
  Point(this.x, this.y);
}

默认构造器

如果我们显式声明构造函数,Dart会提供一个默认的构造器。默认的构造其不含参数。

构造器不会被继承

子类不会继承父类的构造器。没有声明构造器的子类会有一个默认的构造器。

最后

本文正在参加「金石计划 . 瓜分6万现金大奖」

谢谢~