企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
# 面向对象扩展 封装:有效设计一个类,组装属性和方法 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; } } } ~~~