likes
comments
collection
share

第130期:Dart基础知识(类01)

作者站长头像
站长
· 阅读数 14

封面图

第130期:Dart基础知识(类01)

11.09 9:00 接通知居家办公,文章接上文继续讲Dart中的类

Methods 类的方法

方法也是函数,提供了类的各种操作行为。对象上的实例方法可以访问实例中的变量以及this。比如:

import 'dart:math';

class Point {
  final double x;
  final double y;

  Point(this.x, this.y);

  double distanceTo(Point other) {
    var dx = x - other.x;
    var dy = y - other.y;
    return sqrt(dx * dx + dy * dy);
  }
}

dart:math 是Dart核心库中的数学运算相关的包。Dart的形式和node有些相似,有各种包管理。

Abstract classes 抽象类

abstract标识符可以定义一个抽象类。抽象类在定义接口时非常有用,如果我们希望我们的抽象类可以进行实例化,我们可以定义一个构造函数:

// This class is declared abstract and thus
// can't be instantiated.
abstract class AbstractContainer {
  // Define constructors, fields, methods...

  void updateChildren(); // Abstract method.
}

这种写法和TS非常类似,抽象类作为其他派生类的基类。TS也是使用abstract关键字定义抽象类:

abstract class Animal { 
    abstract makeSound(): void; 
    move(): void { 
        console.log('roaming the earch...'); 
        }
    }

抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。

Implicit interfaces 隐式接口

每个类都会隐式的定义一个接口,该接口包含了这个类所有的实例成员以及它扩展的各种接口。如过我们想要创建一个支持B类API且不继承B,那我们这个类需要扩展B类的接口。

一个类可以扩展一个或者多个接口,我们只需要使用implements语句进行声明即可:

// A person. The implicit interface contains greet().
class Person {
  // In the interface, but visible only in this library.
  final String _name;

  // Not in the interface, since this is a constructor.
  Person(this._name);

  // In the interface.
  String greet(String who) => 'Hello, $who. I am $_name.';
}

// An implementation of the Person interface.
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')));
  print(greetBob(Impostor()));
}

扩展多个接口:

class Point implements Comparable, Location {...}

Extending a class 类的扩展

我们可以使用extends关键字对类进行扩展

class Television {
  void turnOn() {
    _illuminateDisplay();
    _activateIrSensor();
  }
  // ···
}

class SmartTelevision extends Television {
  void turnOn() {
    super.turnOn();
    _bootNetworkInterface();
    _initializeMemory();
    _upgradeApps();
  }
  // ···
}

super 是父类或者超类的一个引用。

override 类成员的覆写

我认识@override是在java语言中,个人理解它其实是一种重载。

子类可以重写实例方法(包括运算符)、getter和setter。我们可以使用@override注释来表示重写成员方法:

class Television {
  // ···
  set contrast(int value) {...}
}

class SmartTelevision extends Television {
  @override
  set contrast(num value) {...}
  // ···
}

TS中目前似乎没有@override

noSuchMethod 无此方法

需要对代码试图使用不存在的方法或实例变量时检测或作出反应,我们可以重写noSuchMethod():

class A {
  // Unless you override noSuchMethod, using a
  // non-existent member results in a NoSuchMethodError.
  @override
  void noSuchMethod(Invocation invocation) {
    print('You tried to use a non-existent member: '
        '${invocation.memberName}');
  }
}

mixins 混入

Mixin是一种在多个类层次结构中重用类代码的方法。

使用mixin, 我们需要使用use关键字后面跟上要混入的类名:

class Musician extends Performer with Musical {
  // ···
}

class Maestro extends Person with Musical, Aggressive, Demented {
  Maestro(String maestroName) {
    name = maestroName;
    canConduct = true;
  }
}

要实现mixin ,我们需要创建换一个继承某个对象的类,且不需要定义构造器。当我们希望mixin可以像一个常规的类进行使用时,我们可以使用mixin关键字进行声明。

mixin Musical {
  bool canPlayPiano = false;
  bool canCompose = false;
  bool canConduct = false;

  void entertainMe() {
    if (canPlayPiano) {
      print('Playing piano');
    } else if (canConduct) {
      print('Waving hands');
    } else {
      print('Humming to self');
    }
  }
}

有时我们可能希望限制可以使用mixin的类型。例如,mixin可能取决于能否调用mixin未定义的方法。如以下示例所示,可以通过使用on关键字指定所需的超类来限制mixin的使用:

class Musician {
  // ...
}
mixin MusicalPerformer on Musician {
  // ...
}
class SingerDancer extends Musician with MusicalPerformer {
  // ...
}