Classes
Dart is an object-oriented language with classes and mixin-based inheritance. Every object is an instance of a class, and all classes except Null descend from Object. Mixin-based inheritance means that although every class (except for the top class, Object) has exactly one superclass, a class body can be reused in multiple class hierarchies.
Using constructors
constant
void main() {
var a = const ImmutablePoint(1, 1);
var b = const ImmutablePoint(1, 1);
print(identical(a, b)); // T
}
class ImmutablePoint {
final int x;
final int y;
const ImmutablePoint(this.x, this.y);
}
// Lots of const keywords here.
const pointAndLine = const {
'point': const [const ImmutablePoint(0, 0)],
'line': const [const ImmutablePoint(1, 10), const ImmutablePoint(-2, 11)],
};
// Only one const, which establishes the constant context.
const pointAndLine = {
'point': [ImmutablePoint(0, 0)],
'line': [ImmutablePoint(1, 10), ImmutablePoint(-2, 11)],
};
这个const简写只要写一段时间flutter就会缝进肌肉记忆,疯狂报warning;
Getting an object’s type
Use a type test operator rather than runtimeType to test an object’s type. In production environments, the test object is Type is more stable than the test object.runtimeType == Type.
print('The type of a is ${
a.runtimeType}');
Instance variables
All uninitialized instance variables have the value null.
All instance variables generate an implicit getter method.
Non-final instance variables and late final instance variables without initializers also generate an implicit setter method.
If you initialize a non-late instance variable where it’s declared, the value is set when the instance is created, which is before the constructor and its initializer list execute. As a result, non-late instance variable initializers can’t access this.
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.
}
注意这个unnamed constuctor, 下一节还会介绍;
void main() {
var a = ProfileMark('a');
var b = ProfileMark.unnamed();
print(a.name);
print(b.name);
}
class ProfileMark {
final String name;
final DateTime start = DateTime.now();
ProfileMark(this.name);
ProfileMark.unnamed() : name = '';
}
final 成员变量尽量初始化掉,如果非要延迟初始化:
-
Use a factory constructor.
-
Use late final, but be careful: a late final without an initializer adds a setter to the API.
Implicit interfaces
菀菀类卿; 可多声明;
class Point implements Comparable, Location {
...}
注意下重写 _name 和 greet();
// 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 variables and methods
static
Static variables aren’t initialized until they’re used.
class Queue {
static const initialCapacity = 16;
// ···
}
Static methods (class methods) don’t operate on an instance, and thus don’t have access to this.
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 =