美文网首页
Dart语法面向对象之2

Dart语法面向对象之2

作者: 学到不懂为止 | 来源:发表于2021-11-21 19:46 被阅读0次

    面向对象扩展

    概要

    继承,继承中的构造方法
    抽象类
    接口
    Mixins,操作符的覆写

    1.继承

    • 使用关键字 extends 继承一个类
    • 子类会继承父类可见的属性和方法,不会继承构造方法
    • 子类能够复写父类的方法,getter 和 setter
    • 单继承,多态性
    // 父类
    class Person {
      String name;
      int age;
      String _birthday;
    
      bool get isAdult => age > 18;
    
      void run() {
          print("Person run...");
      }
    
      // 这个方法是继承 Object 类,Dart语言中类未指定父类的,默认都是继承 Object类
      @override
      String toString() {
          return "Name is $name,Age is $age";
      }
    }
    
    // 继承于 Person 类的子类
    class Student extends Person {
      void study() {
        print("Student study...");
      }
      
      // 复写父类的计算属性
      @override
      bool get isAdult => age > 15;
    
      // 复写父类的 run() 方法
      @override
      void run() {
        print("Student run...");
      }
    }
    
    void main() {
      var student = new Student();
      student.study();
    
      // 访问父类属性,但不能访问私有属性(如: _birthday属性)
      student.name = "Tow";
      student.age = 16;
      print(student.isAdult);
    
      // 访问父类方法
      student.run();
      
      // 多态
      // person 接收一个 Student 类实例,可访问 Person 类的方法属性,不可访问 Sutdent 类方法属性。
      Person person = new Student();
      // 通过对象操作符,判断是否 Student 类,条件满足则 if 里可以访问 study() 方法
      if (person is Student) {
        person.study();
      }
    
      // 会执行 Person 类中的 toString() 方法
      print(person);
    }
    
    1. 继承中的构造方法
    • 子类的构造方法默认会调用父类的无名无参构造方法
    • 如果父类没有无名无参构造方法,则需要显示调用父类构造方法
    • 在构造方法参数后使用 : 显示调用父类构造方法
    // 父类
    class Person {
      String name;
    
      // 无名无参构造方法,默认方法
      // Person() {
      //  // 可加入一些 code
      //  print("Person...");
      //}
      
      // 自定义构造
      Person(this.name);
      Person.withName(this.name);
    }
    
    // 子类
    class Student extends Person {
      int age;
    
      // 必须实现父类构造方法来实现子类构造方法
      Student(String name) : super(name);
      // 或者写成
      Student(String name) : super.withName(name);
      // 或者写成
      Student.withAge(int age) : super(name);
    }
    
    void main() {
      var student = new Student("Tom");
      print(student.name);
    }
    
    • 构造方法执行顺序
      • 父类的构造方法在子类构造方法体开始执行的位置调用
      • 如果有初始化列表,初始化列表会在父类构造方法之前执行
    // 父类
    class Person {
      String name;
    
      // 无名无参构造方法,默认方法
      // Person() {
      //  // 可加入一些 code
      //  print("Person...");
      //}
      
      // 自定义构造
      Person(this.name);
      Person.withName(this.name);
    }
    
    // 子类
    class Student extends Person {
      int age;
      final String gender;
    
      // 必须实现父类构造方法来实现子类构造方法
      // 有初始化列表,初始化列表会在父类构造方法之前执行
      Student(String name, String g) : gender = g, super(name);
      // 错误书写
      Student(String name, String g) : super(name), gender = g;
    }
    
    void main() {
      var student = new Student("Tom", "Male");
      print(student.name);
    }
    
    1. 抽象类
    • 抽象类使用 abstract 表示,不能直接被实例化
    • 抽象方法不用 abstract 修饰,无实现
    • 抽象类可以没有抽象方法
    • 有抽象方法的类一定得声明为抽象类
    abstract class Person {
      // 无实现的抽象方法,子类必须实现方法
      void run();
      // 或者写成,子类可选实现方法
      void run() {}
    }
    
    // 子类继承抽象类
    class Student extends Person {
      @override
      void run() {
        print("run...");
      }
    }
    
    void main() {
      var student = new Student();
      student.run();
    }
    
    1. 接口
    • 类和接口是统一的,类就是接口
    • 每个类都隐式的定义了一个包含所有实例成员的接口
    • 如果是复用已有类的实现,使用继承 extends
    • 如果只是使用已有类的外在行为,使用接口 implements
    // 接口代码演示
    class Person {
      String name;
      int get age => 18;
      void run() {
        print("Person run...");
      }
    }
    
    class Student implements Person {
      // 重写实现
      @override
      String name;
    
      // 重写实现
      @override
      int get age => null;
    
      // 重写实现
      @override
      void run() {
        
      }
    }
    
    void main() {
      var student = new Student();
      student.run();
    }
    
    // 推荐抽象类方式,去对外接口定义
    abstract class Person {
      void run();
    }
    
    class Student implements Person {
      @override
      void run() {
        print("Student run...");
      }
    }
    
    void main() {
      var student = new Student();
      student.run();
    }
    
    1. Mixins
    • Mixins 类似于多继承,是在多类继承中重用一个类代码的方式
    • 作为Mixins的类不能有显示声明构造方法
    • 作为Mixins的类只能继承自Object
    • 使用关键字with连接一个或多个Mixin
    // Mixins 例子
    void main() {
      var d = new D();
      // 打印 ``with``连接的最后一个 ``Mixin`` 类中的``a()``方法
      // 打印结果:"C.a()..."
      d.a();
    }
    
    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()...");
      }
    }
    
    // B,C类是``Mixins``类,类中不能有显示声明构造方法,只能继承自``Object``
    class D extends A with B,C {
      
    }
    
    // Mixins 例子
    abstract class Engine {
      void work();
    }
    
    class OilEngine implements Engine {
      @override
      void work() {
        print("work with oil...");
      }
    }
    
    class ElectricEngine implements Engine {
      @override
      void work() {
        print("work with Electric...");
      }
    }
    
    class Tyre {
      String name;
      void run() {}
    }
    
    // 使用``Mixins``时,正常书写方法
    class Car extends Tyre with ElectricEngine {
      String type;
    }
    
    // 使用``Mixins``时,可书写这种是简写方式,但``Car``、``Bus``类不能自定义属性方法
    class Car = Tyre with ElectricEngine;
    class Bus = Tyre with OilEngine;
    
    
    1. 操作符覆写
    • 覆写操作符需要在类中定义

    返回类型 operator 操作符 (参数1,参数2,...) {
    实现体...
    return 返回值
    }

    • 如果覆写==,还需要覆写对象的hashCode getter方法,可以通过编译器直接覆写,在编辑区右击选择Generate,再选择==() and hashCode, 弹出属性选择框如有多个属性可选择多个属性相等时,类才相等
    • 操作符覆写要定义在类里
    • 可覆写操作符,如图: 可覆写的操作符.png
    // 例子
    void main() {
      var person1 = new Person(10);
      var person2 = new Person(20);
      // 比较
      print(preson1 > person2);
      
      // 取值打印
      print(person1.age);
      print(person1['age']);
    
      // 是否相等,``==`` 这操作符是通过编译器帮覆写了
      print(person1 == person2);
    }
    
    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;
        }
        return 0;
      }
    }
    

    相关文章

      网友评论

          本文标题:Dart语法面向对象之2

          本文链接:https://www.haomeiwen.com/subject/hozptrtx.html