Dart 类:抽象类、多态、继承、接口、及 Mixins

2019年9月14日10:47:58 发表评论 117 views

09 Dart中的对象 类

09-1 对象 类

  • 面向对象编程(OOP)的三个基本特征是:封装、继承、多态
    • 封装:封装是对象和类概念的主要特性。封装,把客观事物封装成抽象的类,并且把自己的部分属性和方法提供给其他对象调用, 而一部分属性和方法则隐藏。
    • 继承:面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
    • 多态:允许将子类类型的指针赋值给父类类型的指针, 同一个函数调用会有不同的执行效果 。
  • Dart所有的东西都是对象,所有的对象都继承自Object类。
  • Dart是一门使用类和单继承的面向对象语言,所有的对象都是类的实例,并且所有的类都是Object的子类
  • 一个类通常由属性和方法组成。
  class Person {
    // String name = '张三';
    // int age = 32;
    String name;
    int age;

    // 构造函数在实例化的时候触发
    // Person() {
      // print('构造函数在实例化的时候触发');
    // }

    // Person(String name, int age) {
      // this.name = name;
      // this.age = age;
    // }

    Person(this.name, this.age);

    // 命名构造函数
    Person.setInfo(String name, int age) {
      this.name = name;
      this.age = age;
    }

    void getInfo() {
      print('${this.name}---${this.age}');
    }

    void setInfo(int age) {
      this.age = age;
    }
  }

  void main() {
    Person p2 = new Person('Hiraku', 29);
    p2.setInfo(28);
    p2.getInfo();

    Person p3 = new Person.setInfo('Hiraku', 29);
    p3.getInfo();
  }
复制代码

09-2 私有属性

  • dart 中没有私有属性和私有方法,不像其他面向对象的语言有 public private protected 等修饰符
  • 将类单独抽离到一个文件夹,然后加上 _ 表示私有属性

09-3 类中的 setter 和 getter

  • setter
class Reac {
  num height;
  num width;

  Reac(this.height, this.width);

  get area {
    return this.height * this.width;
  }
}

void main() {
  Reac r = new Reac(8, 16);

  print('面积:${r.area}');
}
复制代码
  • getter
class Reac {
  num height;
  num width;

  Reac(this.height, this.width);

  set reacHeight(num val) {
    this.height = val;
  }

  get area {
    return this.height * this.width;
  }
}

void main() {
  Reac r = new Reac(8, 16);
  r.reacHeight = 1;

  print('面积:${r.area}');
}
复制代码

09-4 类里面的初始化列表

class Reac {
  num height;
  num width;

  Reac():height = 20, width = 30{
    print('${this.height}===${this.width}');
  }

  set reacHeight(num val) {
    this.height = val;
  }

  get area {
    return this.height * this.width;
  }
}

void main() {
  Reac r = new Reac();

  print('面积:${r.area}');
}
复制代码

10 Dart中的类 静态成员 操作符 类的继承

10-1 Dart中的静态成员:

  • 1、使用static 关键字来实现类级别的变量和函数
  • 2、静态方法不能访问非静态成员,非静态方法可以访问静态成员
class Person {
  static String name = '张三';
  static void show() {
    print(name);
  }
}

void main() {
  print(Person.name);
  Person.show();  
}
复制代码
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();
  }
}

void main() {
  // print(Person.name);
  // Person.show(); 

  // Person p = new Person();
  // p.printInfo(); 

  Person.printUserInfo();
}
复制代码

10-2 Dart中的对象操作符

  • ? 条件运算符 (了解)
  • as 类型转换
  • is 类型判断
  • .. 级联操作 (连缀) (记住)
  class Person {
    String name;
    int age;
    Person(this.name, this.age);

    printInfo() {
      print('${this.name}--${this.age}');
    }
  }

  void main() {
    Person p;
    p.printInfo(); // 报错

    p?.printInfo();

    print(p is Person); // true
    print(p is Object); // true
  }

  void main() {
    var p1;
    p1 = '';
    p1 = new Person();
    (p1 as Person).printInfo();
  }

  void main() {
    Person p1 = new Person('Hiraku', 29);
    p1.printInfo(); // Hiraku--29

    p1.name = '马红琴';
    p1.age = 18;
    pi.printInfo(); // 马红琴--18

    p1..name = '马红琴'
      ..age = 18
      ..pringInfo(); // 马红琴--18
  }
复制代码

10-3 面向对象的三大特性:封装 、继承、多态

  • Dart中的类的继承:
    • 1、子类使用 extends 关键词来继承父类
    • 2、子类会继承父类里面可见的属性和方法 但是不会继承构造函数
    • 3、子类能复写父类的方法 gettersetter

class Person {
  String name;
  int age;

  Person(this.name, this.age);
  Person.work(this.name) { // 命名构造函数
    print('${this.name} is working');
  };

  void printInfo() {
    print('${this.name}--${this.age}');
  }

  void isJoking() {
    print('${this.name}---is joking');
  }
}

class Web extends Person {
  String sex;

  Web(String name, int age, String sex) : super(name, age) {
    this.sex = sex;
  }

  void printFun() {
    print('${this.name}--${this.age}--${this.sex}');
  }
}

class Design extends Person {
  String sex;

  Design(String name, int age, String sex) : super.work(name) {
    this.age = age;
    this.sex = sex;
  }

  void printFun() {
    super.isJoking(); // 子类调用父类的方法
    print('${this.name}--${this.age}--${this.sex}');
  }

  @overage
  void printInfo() { // 复写父类方法
    print('姓名:${this.name}');
  }
}

void main() {
  Web w = new Web('Hiraku', 29, '女');
  Design d = new Design('Hiraku', 29, '女');

  w.printFun();
  d.printFun();
}
复制代码

11 Dart中的抽象类 多态 以及接口

11-1 Dart 中的抽象类

  • Dart中抽象类: Dart 抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。
    • 1、抽象类通过 abstract 关键字来定义
    • 2、Dart 中的抽象方法不能用 abstract 声明,Dart 中没有方法体的方法我们称为抽象方法。
    • 3、如果子类继承抽象类必须得实现里面的抽象方法
    • 4、如果把抽象类当做接口实现的话必须得实现抽象类里面定义的所有属性和方法。
    • 5、抽象类不能被实例化,只有继承它的子类可以
  • extends 抽象类和 implements 的区别:
    • 1、如果要复用抽象类里面的方法,并且要用抽象方法约束自类的话我们就用 extends 继承抽象类
    • 2、如果只是把抽象类当做标准的话我们就用 implements 实现抽象类

11-2 Dart 中的多态

  • 允许将子类类型的指针赋值给父类类型的指针, 同一个函数调用会有不同的执行效果
  • 子类的实例赋值给父类的引用
  • 多态就是父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现
abstract class Animal { // 抽象类用 abstract 定义
  Animal();
  eat(); // 抽象方法,主要用来约束子类,不能使用 abstract 定义,而是没有方法体的方式定义抽象方法
  run();

  printCommonFunc() {
    print('我是抽象类的抽象方法');
  }
}

class Dog extends Animal {
  @override
  eat() { // 必须得实现抽象方法
    print('小狗在吃骨头');
  }

  @override
  run() {
    print('小狗在遛弯');
  }

  printInfo() {
    print('我是小狗');
  }
}

class Cat extends Animal {
  @override
  eat() {
    print('小猫在吃猫食');
  }

  @override
  run() {
    print('小猫在散步');
  }

  printInfo() {
    print('我是小猫咪');
  }
}

void main() {
  Dog d = new Dog();
  d.eat();
  d.run();

  Cat c = new Cat();
  c.eat();
  c.run();

  Animal animalDog = new Dog();
  animalDog.eat();
  animalDog.printCommonFunc();
  // animalDog.printInfo();  // 报错,因为子类的实例赋值给父类的引用

  Animal animalCat = new Cat();
  animalCat.eat();
}
复制代码

11-4 dart 中的接口

  • 和Java一样,dart也有接口,但是和Java还是有区别的
    • 首先,dart 的接口没有 interface 关键字定义接口,而是普通类或抽象类都可以作为接口被实现
    • 同样使用 implements 关键字进行实现
    • 但是 dart 的接口有点奇怪,如果实现的类是普通类,会将普通类和抽象中的属性的方法全部需要覆写一遍
    • 而因为抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现像Java接口那样的方式,一般会使用抽象类
    • 建议使用抽象类定义接口
abstract class Db {  // 当作接口:规范 规定
  String uri;  // 数据库连接地址
  add();
  save();
  delete();
}

class Mysql implements Db {
  @override
  String uri;

  @override
  add() {
    // TODO: implement add
    return null;
  }

  @override
  delete() {
    // TODO: implement delete
    return null;
  }

  @override
  save() {
    // TODO: implement save
    return null;
  }
  
}

class MongoDb implements Db {
  @override
  String uri;

  @override
  add() {
    // TODO: implement add
    return null;
  }

  @override
  delete() {
    // TODO: implement delete
    return null;
  }

  @override
  save() {
    // TODO: implement save
    return null;
  }
  
}
复制代码

12 Dart中一个类实现多个接口以及 Dart 中的 Mixins

12-1 实现多个接口

abstract class A {
  String name;
  printA();
}

abstract class B {
  printB();
}

class C implements A,B {  
  @override
  String name;  
  @override
  printA() {
    print('printA');
  }
  @override
  printB() {
    // TODO: implement printB
    return null;
  }
  
}

void main(){
  C c=new C();
  c.printA();

}
复制代码

12-2 实现多个接口

  • mixins 的中文意思是混入,就是在类中混入其他功能
  • 在 Dart 中可以使用 mixins 实现类似多继承的功能
  • 因为 mixins 使用的条件,随着 Dart 版本一直在变,这里讲的是D art2.x 中使用 mixins 的条件:
    • 1、作为 mixins 的类只能继承自 Object,不能继承其他类
    • 2、作为 mixins 的类不能有构造函数
    • 3、一个类可以 mixins 多个 mixins 类
    • 4、mixins 绝不是继承,也不是接口,而是一种全新的特性
  class Animal {
  String name;
  int age;
  Animal(this.name, this.age);

  funcAnimal() {
    print('${this.name}--${this.age}');
  }
}
class A {
  String info = 'This is a attribute in A';

  funcA() {
    print('我是 A');
  }
}

class B {
  funcB() {
    print('我是 B');
  }
}

class C extends Animal with A, B {
  C(String name, int age) : super(name, age);
  funcC() {
    print('我是 C 的方法');
  }
}

void main() {
  C c = new C('小猫', 3);
  c.funcA();
  c.funcB();
  c.funcC();
  c.funcAnimal();
  print(c.info);

  print(c is A); // true
  print(c is Animal); // true
}

作者:HongqinMa
来源:掘金

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: