我们在其他语言中都存在这继承的操作,在 dart 中同样存在,都是使用 extends 关键字来做为继承。下面就详细介绍下 dart 中的继承。
Dart 中的继承操作
-
使用关键字 extends 继承一个类
-
子类会继承父类可见的属性和方法,不会继承构造方法
-
子类能够复写父类的方法,getter 和 setter
- 单继承,多态性
实战
新建一个 Person.dart 文件,作为父类
class Person{
String name;
int age;
// 计算属性
bool get adult => this.age > 18;
// 私有属性,对于子类不可见
String _birthday;
void run(){
print("Person running...");
}
}
子类访问父类中的属性与方法
创建一个子类,用于测试继承,子类访问父类的属性与方法
// 引入 person 文件
import 'Person.dart';
class Student extends Person{
void study(){
print("Student studying...");
}
}
void main(){
Student student = new Student();
// 调用 子类自己的方法
student.study(); // Student studying...
// 访问 父类中的属性
student.age = 20;
// 调用 父类的方法
student.run(); // Person running...
// 访问 父类的计算属性
print(student.adult); // true
}
覆写父类的方法以及计算属性
和 java 中类似,使用 @override 表示覆写。
import 'Person.dart';
class Student extends Perosn{
// 覆写父类的计算属性
bool get adult => this.age > 15;
void study(){
print("Student studying...");
}
@override
void run() {
// 调用父类的方法
super.run();
print("student running...");
}
}
void main(){
Student student = new Student();
student.age = 16;
student.run(); // Person running... student running...
print(student.adult); // true
}
继承中多态的使用
// 引入 person 文件
import 'Person.dart';
class Student extends Person{
void study(){
print("Student studying...");
}
@override
void run() {
// 调用父类的方法
super.run();
print("student running...");
}
}
void main(){
Person person = new Student();
// error: 这里无法访问到 子类的方法,因为使用多态生成的对象是 Person,Person 中没有 study方法
person.study();
// 使用 is 表示将 person 转换为了 Student,下面就可以访问了
if (person is Student) {
person.run();
person.study();
}
}
继承中的构造方法
-
子类的构造方法默认会调用父类的无名无参构造方法
-
如果父类没有无名无参构造方法,则需要显示调用父类的构造方法
-
在构造方法参数后使用 : 显示调用父类构造方法
第一种情况
void main() {
var student = new Person(); // Person...
}
class Person{
// 父类的无参构造方法,一般来说是会省略不写
Person(){
print("Person...");
}
}
class Student extends Person{
}
第二种情况
void main() {
var student = new Student("name"); // object
}
class Person{
String name;
// 父类中的构造器
Person(this.name);
Person.withName(this.name){
print("object");
}
}
class Student extends Person{
// 使用 : super 调用父类的构造方法
// Student(String name) : super(name); 这种写法与下面的写法一致
Student(String name) : super.withName(name);
}
构造方法执行顺序
-
父类的构造方法在子类构造方法体开始执行的位置调用
-
如果有初始化列表,初始化列表会在父类构造方法之前执行
子类的构造方法初始化列表,必须要在父类初始化列表之前,否则就会报错。