Dart学习笔记——面向对象(二)
2021-08-27 本文已影响0人
Jabir_Zhang
继承
简单继承
Dart中的类的继承:
- 子类使用extends关键词来继承父类。
- 子类会继承父类里面可见的属性和方法,但是不会继承构造函数。
- 子类能复写父类的方法 getter和setter。
class Person {
String name='张三';
num age=20;
void printInfo() {
print("${this.name}---${this.age}");
}
}
class Adult extends Person{
}
main(){
Adult w=new Adult();
print(w.name);
w.printInfo();
}
super关键词的使用
// 实例化自类给父类构造函数传参
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
class Adult extends Person{
late String sex;
Adult(String name, num age,String sex) : super(name, age){
this.sex=sex;
}
run(){
print("${this.name}---${this.age}--${this.sex}");
}
}
main(){
Adult a=new Adult('张三', 12,"男");
a.printInfo();
a.run();
}
// 实例化自类给命名构造函数传参
class Person {
String name;
num age;
Person(this.name, this.age);
Person.xxx(this.name, this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
class Adult extends Person {
late String sex;
Adult(String name, num age, String sex) : super.xxx(name, age) {
this.sex = sex;
}
run() {
print("${this.name}---${this.age}--${this.sex}");
}
}
main() {
Adult a = new Adult('张三', 12, "男");
a.printInfo();
a.run();
}
覆写父类的方法和调用父类方法
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
work(){
print("${this.name}在工作...");
}
}
class Adult extends Person{
Adult(String name, num age) : super(name, age);
run(){
print('run');
super.work(); //子类调用父类的方法
}
//覆写父类的方法
@override //可以写也可以不写 建议在覆写父类方法的时候加上 @override
void printInfo(){
print("姓名:${this.name}---年龄:${this.age}");
}
@override
work(){
print("${this.name}的工作是写代码");
}
}
main(){
Adult a=new Adult('李四',20);
a.printInfo();
a.work();
}
多态
Dart中抽象类: Dart抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。
- 抽象类通过abstract 关键字来定义。
- Dart中的抽象方法不能用abstract声明,Dart中没有方法体的方法我们称为抽象方法。
- 如果子类继承抽象类必须得实现里面的抽象方法。
- 如果把抽象类当做接口实现的话必须得实现抽象类里面定义的所有属性和方法。
- 抽象类不能被实例化,只有继承它的子类可以。
extends抽象类 和 implements的区别:
- 如果要复用抽象类里面的方法,并且要用抽象方法约束自类的话我们就用extends继承抽象类。
- 如果只是把抽象类当做标准的话我们就用implements实现抽象类。
抽象类实现多态(extends)
//定义一个Animal 类要求它的子类必须包含eat和run方法
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('小猫在跑');
}
}
main(){
Dog d=new Dog();
d.eat();
d.printInfo();
Cat c=new Cat();
c.eat();
c.printInfo();
// Animal a=new Animal(); //抽象类没法直接被实例化
Animal a=new Dog();
a.eat();
}
接口(implements)
和Java一样,dart也有接口,但是和Java还是有区别的。
首先,dart的接口没有interface关键字定义接口,而是普通类或抽象类都可以作为接口被实现。
同样使用implements关键字进行实现。
但是dart的接口有点奇怪,如果实现的类是普通类,会将普通类和抽象中的属性的方法全部需要覆写一遍。
而因为抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现像Java接口那样的方式,一般会使用抽象类。
/*
定义一个DB库 支持 mysql mssql mongodb
mysql mssql mongodb三个类里面都有同样的方法
*/
abstract class Db{ //当做接口 接口:就是约定 、规范
late String uri; //数据库的链接地址
add(String data);
save();
delete();
}
class Mysql implements Db{
@override
String uri;
Mysql(this.uri);
@override
add(data) {
print('这是mysql的add方法'+data);
}
@override
delete() {
return null;
}
@override
save() {
return null;
}
remove(){
}
}
class MsSql implements Db{
@override
late String uri;
@override
add(String data) {
print('这是mssql的add方法'+data);
}
@override
delete() {
return null;
}
@override
save() {
return null;
}
}
main() {
Mysql mysql=new Mysql('xxxxxx');
mysql.add('1243214');
}
多个接口
abstract class A{
late String name;
printA();
}
abstract class B{
printB();
}
class C implements A,B{
@override
late String name;
@override
printA() {
print('printA');
}
@override
printB() {
// TODO: implement printB
return null;
}
}
void main(){
C c=new C();
c.printA();
}
mixins("多继承")
mixins的中文意思是混入,就是在类中混入其他功能。
在Dart中可以使用mixins实现类似多继承的功能。
因为mixins使用的条件,随着Dart版本一直在变,这里讲的是Dart2.x中使用mixins的条件:
- 作为mixins的类只能继承自Object,不能继承其他类
- 作为mixins的类不能有构造函数
- 一个类可以mixins多个mixins类
- 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();
c.printA();
c.printB();
print(c.info);
}
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("A 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);
}
void main(){
var c=new C('张三',20);
c.printInfo();
c.printB();
print(c.info);
c.run();//A Run
}
Person、B、A类中都有run方法,为何c.run()打印的是A Run,留给大家思考。
mixins的实例类型是什么?
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
}
泛型
通俗理解:泛型就是解决、类、接口、方法的复用性、以及对不特定数据类型的支持(类型校验)
//不指定类型
getData(value){
return value;
}
//不指定类型放弃了类型检查。传入和返回都进行检查
T getData<T>(T value){
return value;
}
//放弃了返回的类型检查。传入进行检查
getData<T>(T value){
return value;
}
void main(){
print(getData(21));
print(getData('xxx'));
getData<String>('你好');//对传入类型指定为String
print(getData<int>(12));//对传入类型指定为int
}
泛型类
系统List就是一个泛型类,可以指定类型。
List list = new List<String>.filled(2, "");
list[0] = "张三";
list[1] = "李四";
print(list);
List list2 = new List<int>.filled(2, 0);
list2[0] = 12;
list2[1] = 13;
print(list2);
class MyList<T> {
List list = <T>[];
void add(T value) {
this.list.add(value);
}
List getList() {
return list;
}
}
main() {
//不指定类型
MyList l1=new MyList();
l1.add("张三");
l1.add(12);
l1.add(true);
print(l1.getList());
//指定String类型
MyList l2 = new MyList<String>();
l2.add("张三1");
// l2.add(11); //错误的写法
print(l2.getList());
//指定int类型
MyList l3 = new MyList<int>();
l3.add(11);
l3.add(12);
l3.add("aaaa");
print(l3.getList());
}
泛型接口
abstract class Cache<T>{
getByKey(String key);
void setByKey(String key, T value);
}
class FlieCache<T> implements Cache<T>{
@override
getByKey(String key) {
return null;
}
@override
void setByKey(String key, T value) {
print("我是文件缓存 把key=${key} value=${value}的数据写入到了文件中");
}
}
class MemoryCache<T> implements Cache<T>{
@override
getByKey(String key) {
return null;
}
@override
void setByKey(String key, T value) {
print("我是内存缓存 把key=${key} value=${value} -写入到了内存中");
}
}
void main(){
MemoryCache m=new MemoryCache<String>();
m.setByKey('index', '首页数据');
MemoryCache m1=new MemoryCache<Map>();
m1.setByKey('index', {"name":"张三","age":20});
}