Flutter 中的三种关系:
- 1、继承(关键字
extends
) - 2、混入 mixins (关键字
with
) - 3、接口实现(关键字
implements
) - 这三种关系可以同时存在,但是有前后顺序:extends -> mixins -> implements。extens在前,mixins在中间,implements最后。
类
- Dart所有的东西都是对象,所有的对象都继承自Object类。
- Dart是一门使用类和单继承的面向对象语言,所有的对象都是类的实例,并且所有的类都是Object的子类。
构造函数
默认构造函数
- dart的默认构造函数只能有一个,由类名+(参数s){}构成
Person(String name,int age){this.name = name; this.age = age;}
- 默认构造函数简写格式为类名+(接收参数的属性s)
Person(this.name, this.age);// 将接收到的第一个参数赋值给this.name,接收到的第二个参数,赋值给this.age,等同于上面的Person(String name,int age){this.name = name; this.age = age;}
命名构造函数
- dart 中命名构造函数可以有多个
- 命名构造函数格式为类名.函数名(参数s) { }
Person.student(){函数体}
。使用命名构造函数生成一个实例:Person p = new Person.student();
Dart中的私有属性和方法
- dart中没有public、private、protected访问修饰符
- dart中使用下划线(_)将一个属性或者方法变为私有。需要注意的是加了下划线的私有属性或者方法依然可以被当前文件中的其他类访问,只是不能被别的文件中的模块访问。如果需要只能当前类访问,需要将该类放到一个单独的文件中
。
getter 和 setter
class Rect{
num height;
num width;
//Rect(this.height,this.width);
Rect():height=2,width=10{//在构造函数体运行之前初始化实例变量
}
get area{
return this.height*this.width;
}
set areaHeight(value){
this.height=value;
}
}
静态成员和静态方法
- dart中使用static关键字来实现类级别的变量和函数
- 静态方法不能访问非静态成员,非静态成员方法可以访问静态成员
class Person {
static String name = '张三';
int age=20;
static void show() {
print(name);
}
void printInfo(){ /*非静态方法可以访问静态成员以及非静态成员*/
print(name); //访问静态属性
print(this.age); //访问非静态属性
show(); //调用静态方法
}
static void printUserInfo(){//静态方法
print(name); //静态属性
show(); //静态方法
// print(this.age); //静态方法没法访问非静态的属性 报错
// this.printInfo(); //静态方法没法访问非静态的方法 报错
// printInfo(); //静态方法没发访问非静态的方法 报错
Person p = Person();
p.printInfo();
}
}
继承
- 子类使用extends关键词来继承父类
- 子类会继承父类里面可见的属性和方法 但是不会继承构造函数(默认构造函数和命名构造函数)
- 子类能复写父类的方法 getter和setter
- 子类重写父类方法时用@override关键字,默认不用也可以,一般建议使用
- 子类中使用super关键字调用父类方法
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
class Web extends Person{
Web(String name, num age) : super(name, age){ //子类实现自己的构造方法,同时调用父类的构造方法
}
}
抽象类
- Dart抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。
- 抽象类通过abstract 关键字来定义
- Dart中的抽象方法不能用abstract声明,Dart中没有方法体的方法我们称为抽象方法。
- 如果子类继承抽象类必须得实现里面的抽象方法
- 如果把抽象类当做接口实现的话必须得实现抽象类里面定义的所有属性和方法。
- 抽象类不能被实例化,只有继承它的子类可以
extends抽象类 和 implements的区别:
- 如果要复用抽象类里面的方法,并且要用抽象方法约束自类的话我们就用extends继承抽象类
- 如果只是把抽象类当做标准的话我们就用implements实现抽象类
abstract class Animal{
eat(); //抽象方法
run(); //抽象方法
printInfo(){
print('我是一个抽象类里面的普通方法');
}
}
class Dog extends Animal{
@override
eat() {
print('小狗在吃骨头');
}
@override
run() {
print('小狗在跑');
}
}
class Cat extends Animal{
@override
eat() {
print('小猫在吃老鼠');
}
@override
run() {
print('小猫在跑');
}
}
Dart 中的多态
- 允许将子类类型的指针赋值给父类类型的指针, 同一个函数调用会有不同的执行效果 。
- 子类的实例赋值给父类的引用。
- 多态就是父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现。
Dart中的接口
- dart的接口没有interface关键字定义接口,而是普通类或抽象类都可以作为接口被实现。
- 使用implements关键字进行实现
- 如果实现的类是普通类,会将普通类和抽象中的属性的方法全部需要覆写一遍。因为抽象类可以定义抽象方法,普通类不可以.
Dart 中的接口
- 一个类实现多个接口
abstract class A{
String name;
printA();
}
abstract class B{
printB();
}
class C implements A,B{
@override
String name;
@override
printA() {
print('printA');
}
@override
printB() {
return null;
}
}
Dart 中的混入
- mixins意思是混入,就是在类中混入其他功能。
- 在Dart中可以使用mixins实现类似多继承的功能
- mixins使用的条件,随着Dart版本一直在变,这里说的是Dart2.x中使用mixins的条件:
1、作为mixins的类只能继承自Object,不能继承其他类
2、作为mixins的类不能有构造函数
3、一个类可以mixins多个mixins类
4、mixins绝不是继承,也不是接口,而是一种全新的特性
class Person{
String name;
num age;
Person(this.name,this.age);
printInfo(){print('${this.name}----${this.age}');}
void run(){print("Person Run");}
}
class A {
String info="this is A";
void printA(){ print("A");}
void run(){print("run")}
}
class B {
void printB(){print("B");}
void run(){print("B Run");}
}
class C extends Person with B,A{
C(String name, num age) : super(name, age);
}
- mixins的类型就是其超类的子类型。
class A {
String info="this is A";
void printA(){
print("A");
}
}
class B {
void printB(){
print("B");
}
}
class C with A,B{
}
void main(){
var c=new C();
print(c is C); //true
print(c is A); //true
print(c is B); //true
}
抽象类
抽象方法:在Dart中没有具体实现的方法(没有方法体),就是抽象方法,抽象方法必须存在于抽象类中
抽象类里的方法可以有实现,也可以仅仅声明
抽象类使用abstract声明
external 的作用: 可以是方法的声明和实现分离,这样多的好处是可以针对不同平台做不同实现
注意一:抽象类不能实例化。我们的Map虽然是个抽象类,但是可以创造Map实例(var map = Map()),是因为Map提供了一个工厂方法(返回一个子类实例);源码为: external factory Map(); 在dart的源码中可以看到实现为: factory Map() => LinkedHashMap<K,V>();
注意二:抽象类中的抽象方法必须被子类实现, 抽象类中的已经被实现方法, 可以不被子类重写.隐式接口
Dart中的接口比较特殊, 没有一个专门的关键字来声明接口.
默认情况下,定义的每个类都相当于默认也声明了一个接口,可以由其他的类来实现(因为Dart不支持多继承)
在开发中,我们通常将用于给别人实现的类声明为抽象类:
abstract class Run {
run();
}
class Fly { // 这里我们也可以把Fly类当做一个接口
print('fly');
}
}
class SuperMan implements Run, Fly { // implements用来实现接口,实现的接口不可以调super方法
@override
run() {
print('超人在奔跑');
}
@override
fly() {
print("fuperman fly");
}
}
- 混入(Mixin)
在通过implements实现某个类时,类中所有的方法都必须被重新实现(无论这个类原来是否已经实现过该方法)。
但是某些情况下,一个类可能希望直接复用之前类的原有实现方案,怎么做呢?
使用继承吗?但是Dart只支持单继承,那么意味着你只能复用一个类的实现。
Dart提供了另外一种方案: Mixin混入的方式
除了可以通过class定义类之外,也可以通过mixin关键字来定义一个类。
只是通过mixin定义的类用于被其他类混入使用,通过with关键字来进行混入。
mixin Runner {
run() {
print('在奔跑');
}
}
mixin Flyer {
fly() {
print('在飞翔');
}
}
// implements的方式要求必须对其中的方法进行重新实现
// class SuperMan implements Runner, Flyer {}
class SuperMain with Runner, Flyer {
}
调用顺序,有自己的实现用自己的实现,没有自己的实现用混入的实现,没有混入的实现用继承的实现,如果都没有就报方法找不到的错误了