Dart 笔记 9 - 类(2)
2019-01-15 本文已影响0人
三流之路
抽象类
加 abstract 关键字,抽象方法没有实现体,不需要 abstract 关键字。
abstract class Doer {
void doSomething();
}
class EffectiveDoer extends Doer {
void doSomething() {
}
}
隐式接口
每个类都隐式地定义一个接口,该接口包含类的所有实例成员及其实现的任何接口。如果想创建一个类 A,它支持类 B 的 API 而不继承 B 的实现,那么类 A 应该实现 B 接口。
// 有个隐式的接口,包含实例方法 greet().
class Person {
// In the interface, but visible only in this library.
final _name;
// 构造方法不在隐式接口里
Person(this._name);
// 在隐式接口里
String greet(String who) => 'Hello, $who. I am $_name.';
}
// 用实现而不是继承
class Impostor implements Person {
get _name => '';
// 如果继承必须要有构造方法
// 实现必须重写 greet 方法
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?
}
重写方法
子类可以覆盖实例方法、getter 和 setter。可以使用 @override
注解来指示重写了某个成员方法。
class Television {
void turnOn() {
_illuminateDisplay();
_activateIrSensor();
}
// ···
}
class SmartTelevision extends Television {
// 重写方法
void turnOn() {
super.turnOn(); // 使用 super 表示父类的方法
_bootNetworkInterface();
_initializeMemory();
_upgradeApps();
}
// ···
}
重写操作符
可以重写这些操作符:<
、+
、|
、[]
、>
、/
、^
、[]=
、<=
、~/
、&
、~
、>=
、*
、<<
、==
、-
、%
、>>
。类似 Kotlin。
class Vector {
final int x, y;
Vector(this.x, this.y);
Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
Vector operator -(Vector v) => Vector(x - v.x, y - v.y);
}
void main() {
final v = Vector(2, 3);
final w = Vector(2, 2);
assert(v + w == Vector(4, 5));
assert(v - w == Vector(0, 1));
}
如果重写
==
,还应该重写对象的 hashCode getter。
hashCode
每个对象自动地提供了一个整数哈希码,因此可以作为映射中的键。但是,重写 hashCode getter 来生成自定义哈希代码。如果这样做,可能还想重写 ==
操作符。相等的对象必须具有相同的哈希码。
class Person {
final String firstName, lastName;
Person(this.firstName, this.lastName);
@override
int get hashCode {
int result = 17;
result = 37 * result + firstName.hashCode;
result = 37 * result + lastName.hashCode;
return result;
}
@override
bool operator ==(dynamic other) {
if (other is! Person) return false;
Person person = other;
return (person.firstName == firstName &&
person.lastName == lastName);
}
}
void main() {
var p1 = Person('Bob', 'Smith');
var p2 = Person('Bob', 'Smith');
var p3 = 'not a person';
assert(p1.hashCode == p2.hashCode);
assert(p1 == p2);
assert(p1 != p3);
}
noSuchMethod()
可以重写 noSuchMethod() 方法来处理程序访问一个不存在的方法或者成员变量:
class A {
@override
void noSuchMethod(Invocation invocation) {
print('You tried to use a non-existent member: ' +
'${invocation.memberName}');
}
}
mixins 特性
mixin 类似多继承,但不是子类父类的关系,只是获取了一些功能,可以灵活地混入不同的类来实现不同的功能。相比接口,接口只是获得方法名,不包含实现,而 mixin 包含了实现。
要使用 mixin,在 with 关键字后面加上一个或多个 mixin 名称。
class Musician extends Performer with Musical {
// ···
}
class Maestro extends Person
with Musical, Aggressive, Demented {
Maestro(String maestroName) {
name = maestroName;
canConduct = true;
}
}
要实现 mixin,创建一个 Object 的子类,不声明构造函数,也不调用 super。例如:
abstract class 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');
}
}
}