# 面向对象扩展
封装:有效设计一个类,组装属性和方法
1. 继承,继承中的构造方法
2. 抽象类
3. 接口
4. Mixins,操作符的覆写(重载)
## 继承
1. 使用关键字extends继承一个类
2. 子类会继承父类可见的属性和方法,不会继承构造方法
3. 子类能够覆写父类的方法,getter和setter
4. **单继承**,多态性(C++多继承,复杂)
~~~
person.dart
class Person{
String name;
int age;
//私有属性
String _birthday;
//计算属性
bool get isAdult => age > 18;
void run(){
print('Person run ...');
}
}
~~~
student.dart
~~~
import 'person.dart';
void testDart(){
var student = new Student();
student.study();
student.name = "guo";
student.age = 16;
student.run();
print(student.isAdult);
}
class Student extends Person{
void study(){
print('Student study ...');
}
//@override 表示下面的计算属性或方法是从父类继承过来的,可有可无,加上之后知道是覆写的。
@override
// TODO: implement isAdult
bool get isAdult => age>15;
@override
void run() {
// TODO: implement run
//super表示子类调用父类的方法
//super.run();
print('Student run ...');
}
}
~~~
多态
~~~
//把子类的实例赋值给父类的引用,这就是多态
//实例化Student,但是只能访问Person中的属性和方法,不能访问Student的
Person person = new Student();
// 如果一个父类有多个子类实现的话,可以实现很多复杂的问题
// person.study(); 不可访问
if(person is Student){
// 此时可以访问
person.study();
}
~~~
## 继承中的构造方法
1. 子类的构造方法**默认会调用父类的无名无参构造方法**
~~~
class Person{
Person(){
// 会被调用
print('xxxx')
}
}
~~~
2. 如果父类没有无名无参构造方法,则需要显示调用父类构造方法
3. 在构造方法参数后使用 :显示调用父类构造方法。
~~~
class Person{
String name;
Person(this.name);
Person.widthName(this.name);
}
class Student extends Person{
int age;
// 子类的构造方法,需要去显示调用父类构造方法 :super(name); 调用的是Person(){}
Student(String name): super(name);
// 也可以调用命名的构造方法
Student.widthName(String name): super.widthName(name);
}
~~~
## 构造方法的执行顺序
1. 父类的构造方法在子类构造方法体开始之前进行执行
2. 如果有初始化列表,初始化列表会在父类构造方法之前执行
~~~
class Person{
String name;
Person(this.name);
Person.widthName(this.name);
}
class Student extends Person{
int age;
final String gender;
// 初始化类别必须在构造函数之前
Student.widthName(String name, String g): gender = g, super.widthName(name);
}
~~~
## 抽象类
1. 抽象类使用abstract表示,不能直接被实例化
2. 抽象方法不用abstract修饰,无实现
3. 抽象类可以没有抽象方法
4. 有抽象方法的类一定得声明为抽象类
5. 抽象类不能被实例化,需要通过继承的方法让子类实例化
6. 抽象类更像其他语言里的接口,dart中的接口和其他语言不太一样
~~~
void testDart(){
// var person = new Person(); //报错
}
abstract class Person{
void run(); //抽象方法
}
~~~
以下会报错
~~~
class Person{
void run(); //抽象方法
}
~~~
抽象方法继承中实现
~~~
void testDart(){
var person = new Student(); //报错
person.run();
}
abstract class Person{
void run(); //抽象方法
}
class Student extends Person{
@override
void run() {
// TODO: implement run
print('run ...');
}
}
~~~
## 接口
1. dart中,类和接口是统一的,**类就是接口**
2. 每个类都隐式的定义了一个**包含所有实例成员的接口**
3. 如果是**复用已有类的实现,使用继承(extends)**;
4. 如果只是**使用已有类的外在行为,使用接口(implements)**;
~~~
class Person{
String name;
int get age => 18;
void run(){
print('Person run...');
}
}
// 实现接口 把Person(类)作为接口使用,Person类的所有成员作为接口声明的实例变量或方法
class Student implements Person{
// 需要重写里面的所有属性和方法
@override
// TODO: implement name
String get name => null;
@override
// TODO: implement age
int get age => 15;
@override
void run() {
// TODO: implement run
}
}
~~~
抽象类使用接口
~~~
void testDart(){
var person = new Student(); //报错
person.run();
}
abstract class Person{
void run(){
print('Person run...');
}
}
// 这样更新接口
class Student implements Person{
@override
void run() {
// TODO: implement run
print('xxxxxx');
}
}
~~~
## Mixins
1. **Mixins类似于多继承,是在多类继承中重用一个类代码的方式**
2. 作为Mixin的类**不能有显示声明构造方法**(例如B和C)
3. 作为Mixin的类**只能继承自Object**(例如 class C extends Test,C不能作为Mixins)
4. 使用**关键字width连接一个或多个mixin**
class D extends A with B, C
~~~
void testDart(){
var d = new D();
//d 拥有abc三个方法
d.a();
d.b();
d.c();
}
class A{
void a(){
print('A,a(),,,,');
}
}
class B{
void b(){
print('B,b(),,,,');
}
}
class C{
void c(){
print('C,c(),,,,');
}
}
//先有继承,才能有Mixins
class D extends A with B, C{
}
~~~
Mixins顺序
~~~
void testDart(){
var d = new D();
//d 调用的都是C里面的方法
d.a();
d.b();
d.c();
}
class A{
void a(){
print('A,a(),,,,');
}
}
class B{
void a(){
print('B,a(),,,,');
}
void b(){
print('B,b(),,,,');
}
}
class C{
void a(){
print('C,a(),,,,');
}
void b(){
print('C,b(),,,,');
}
void c(){
print('C,c(),,,,');
}
}
// 调用方法和Mixins顺序有关,
class D extends A with B, C{
}
~~~
混入,非常强大的功能
~~~
// 抽象类
abstract class Engine{
void work();
}
// 两个类实现引擎接口 使用接口实现,不是继承,如果使用继承是不能使用Mixin的
class OilEngine implements Engine{
@override
void work() {
print('Work with oil...');
}
}
class ElectricEngine implements Engine{
@override
void work() {
print('Work width electric ...');
}
}
class Tyre{
String name;
void run(){
}
}
class Car = Tyre with ElectricEngine;
// 等价于
class Car1 extends Tyre with ElectricEngine{
//本身具有的属性
String name;
}
class Bus = Tyre with OilEngine;
~~~
## 操作符覆写(重载)
1. 覆写操作符需要在**类中定义**
~~~
返回类型 operator 操作符 (参数1,参数2){
实现体
return 返回值
}
~~~
例子
~~~
void testDart(){
var person1 = new Person(10);
var person2 = new Person(20);
print(person1.age);
print(person2.age);
}
class Person{
int age;
Person(this.age);
bool operator > (Person person){
return this.age > person.age;
}
int operator [](String str){
if('age' == str){
return age;
}
}
}
~~~
- 空白目录
- Flutter入门
- 课程简介
- 开发环境搭建
- 常用组件讲解
- 案例实战
- Dart编程语言入门
- 介绍和开发准备
- 数据类型
- 运算符
- 控制流语句
- 方法
- 面向对象1
- 面向对象2
- 枚举&类型
- Flutter中文网
- Widget框架总览
- 在Flutter中构建布局
- Flutter for Web开发者
- Flutter入门实战
- flutter介绍
- Flutter目录结构,各种组件
- Container、Text
- 图片组件Image
- ListView
- 动态组件
- GridView组件
- 页面布局Padding,Row,Column,Expanded,Icon
- Stack层叠组件,Align,Positioned
- AspectRatio,Cart
- wrap组件
- 组件汇总
