类在每个语言都是最核心的内容。dart 的类与其他语言差别不是很大,但是也有出入。
类属性
类里直接写属性是报错的,必须有默认值初始化或者构造函数赋值。
可以给一个默认值或者可选
代码语言:javascript复制class Person {
String name = "小明";
int age = 3;
String? sex;
}
构造函数
类默认会生成构造函数。构造函数分为:
- 常规类名构造
- 命名构造函数
常规构造函数
常规写法
代码语言:javascript复制Person(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
}
简写
代码语言:javascript复制class Person {
String name = "小明";
int age = 3;
String? sex;
Person(this.name, this.age, this.sex);
}
命名构造函数
以 ClassName.identifier
的方式创建,可以命名多种构造函数。
常规写法
代码语言:javascript复制Person.formJson(Map json) {
this.name = json['name'];
this.age = json['age'];
this.sex = json['sex'];
}
利用:语法,实现简写
代码语言:javascript复制Person.formJson(Map json)
: name = json['name'],
age = json['age'],
sex = json['sex'];
工厂构造函数
dart利用工厂设计模式实现单例构造。
根据名称缓存,一个人名只能对应一个实例吗。比如去找小明,多次声明只能找那一个人。
代码语言:javascript复制class Person {
String name = "小明";
int age = 3;
String? sex;
// Person(this.name, this.age, this.sex);
// Person.formJson(Map json) {
// this.name = json['name'];
// this.age = json['age'];
// this.sex = json['sex'];
// }
// Person.formJson(Map json)
// : name = json['name'],
// age = json['age'],
// sex = json['sex'];
static final Map<String, Person> _cache = <String, Person>{};
factory Person(String name) {
if (_cache.containsKey(name)) {
return _cache[name]!;
} else {
final person = Person._initName(name);
person.age = 21;
_cache[name] = person;
return person;
}
}
Person._initName(this.name);
}
void main(List<String> args) {
// var p1 = Person.formJson({'name': '小红', 'age': 18, 'sex': '男'});
// print(p1.name);
var xiaoming = Person('xiaoming');
print(xiaoming.age);
var xiaoming1 = Person('xiaoming');
xiaoming1.age = 23;
print(xiaoming.age);
}
调用发现最后都是一个实例。
常量构造函数
如果该类生成的对象是固定不变的, 那么就可以把这些对象定义为编译时常量。 为此,需要定义一个 const 构造函数, 并且声明所有实例变量为 final。
代码语言:javascript复制class Person {
final String name;
final int age;
final String? sex;
const Person(this.name, this.age, this.sex);
}
void main(List<String> args) {
var p1 = const Person("xiaoming", 16, "男");
var p2 = const Person("xiaoming", 16, "男");
print(identical(p1, p2));
}
方法
方法是为对象提供行为的函数。
实例方法
普通类的方法
代码语言:javascript复制run() {
print("跑");
}
类方法(静态方法)
静态方法不能使用实例变量
代码语言:javascript复制 static isAdult(age) {
return age > 18 ? true : false;
}
Getter 和 Setter
Getter 和 Setter 是用于对象属性读和写的特殊方法。 回想之前的例子,每个实例变量都有一个隐式 Getter ,通常情况下还会有一个 Setter 。 使用 get 和 set 关键字实现 Getter 和 Setter ,能够为实例创建额外的属性。
代码语言:javascript复制class Rectangle {
num left, top, width, height;
Rectangle(this.left, this.top, this.width, this.height);
// 定义两个计算属性: right 和 bottom。
num get right => left width;
set right(num value) => left = value - width;
num get bottom => top height;
set bottom(num value) => top = value - height;
}
void main() {
var rect = Rectangle(3, 4, 20, 15);
assert(rect.left == 3);
rect.right = 12;
assert(rect.left == -8);
}
继承
dart类肯定也是可以继承的,和其他语言一样。
下面一个例子可以讲明白继承的一些应用:
- 方法的重写
- super 调用父类
- 多态(父类指针指向子类,但是还是子类实例)
class Person {
final String name;
run() {
print('run');
}
Person(this.name);
}
class Student extends Person {
Student(String name) : super(name);
@override
run() {
print("studnet run");
}
}
void main(List<String> args) {
Person s1 = Student('小明');
s1.run(); //studnet run
}