跟着测试代码学会Dart2.x的面向对象

Dart中的方法

  • 方法也是一个对象:使用场景作为参数传递
  • 返回值和参数类型可以省略
  • 当方法的执行语句只有一句的时候:可以使用箭头函数 => 表达式
  • 可选参数:传递参数的时候必须带上形参的名字
  • 匿名方法:没有方法名称的方法
  • 闭包 closure
    • 定义在函数里的函数就是闭包, 闭包也是一个对象.
    • 闭包的作用: 可以访问外部函数的局部变量.
void testClosure() {
    var func = funA();
    func();
    func();
    func();
    func();
    var func2 = funA();
    func2();
    func2();
    func2();
    func2();
}

funA() {
    int count = 0; // 被访问的变量不会被释放
    return () => print(count++); // 这个匿名函数就是一个闭包
}

执行结果

[图片上传失败...(image-ab7c8c-1636857372306)]

Dart的OOP

终端创建一个基于OC的Flutter项目flutter create -objc dart_oop

类和对象

  • 使用class关键字声明一个类
  • 可以使用new跟上构造函数
  • 所有的对象默认都继承Object类
  • Dart中会默认生成getter和setter方法
  • 属性和方法都通过点语法.访问
  • final修饰的属性必须定义初始值
  • 方法名一样, 参数不一样, 方法不能重载!

类的构造函数

  • 一旦定义了构造函数, 默认的构造函数就失效了
  • 当一个对象所有的成员属性都是final的时候, 这个对象可以被创建为常量对象
  • 构造函数前加上const, 常量对象
void main() {
    JHPerson p = JHPerson();
    p.name = 'Jack';
    p.age = 22;
    p.run();
}

class JHPerson {
    final String name2 = 'Jack2'
    String? name;
    int? age;
    int _weight; // 不能被外界跨文件访问, 加上_, 同一份文件可以访问
    final height;
    
    // 初始写法
    JHPerson(int age, String name, int weight) {
        name = name;
        age = age; // 这样写会重名
        _weight = weight;
        final height;// 外面不允许修改
    }
    
    // 语法糖写法, 
    JHPerson(this.name, this.age, this._weight, this.height);
    
    // 命名构造函数
    JHPerson.bigName(this.name, this._weight);
    
    // const修饰构造函数, 创建常量对象
    const JHPerson(this.name, this._weight);
    
    void run() {
        print('$age 岁的 $name 在奔跑♀️')
    }
    
    void _go() {
        print('$_weight 斤的 $name 在Go')
    }
    
    void printP() {
        _go();
    }
    
    void addAge(int age) {
        this.age = age;
    }
}

Dart的工厂构造&单例对象&初始化列表

factory_class.dart

class FactoryClass {
    // 需要一个单列对象
    static FactoryClass? _instance;
    
    factory FactoryClass() => _instance ??= FactoryClass._init();
    //{
    //    if (_instance == null) {
    //      _instance = FactoryClass._init();
    //  }
    //  
    //  return _instance!;
    //    }
    
    // 私有的命名构造函数
    FactoryClass._init();
}

初始化列表

  • 目的:
  • 给final变量赋值
  • 校验传递的参数值
void personDemo() {
    Person p = Person('jack', -1, -2);
}


class Person {
    String name;
    init age;
    final height;
    
    Person(this.name, this.age, int h)
        : height = h,
          assert (h >= 0),
          assert (age >= 0 ){
              print('name:$name age:$age height:$height');
          }
}

类方法和对象操作符

  • 类方法, 静态的static
  • 静态属性用类名访问
void staticDemo(){
        //StaticClass st;
        //st.count;
 
    StaticClass.count = 12;
    print(StaticClass.sum(1));
    
    StaticClass st = StaticClass();
    st.currentCount = 10;
    StaticClass.count = 11;/ /静态的, 在内存中只有一份
    print(st.sum2(20));
    
    StaticClass st2 = StaticClass();
    st2.currentCount = 1;
    print(st2.sum2(20));
}

class StaticClass {
    // 静态属性
    static int count = 1;
    // 实例属性
    int currentCount = 0;
    
    static const String str = 'jack';
    
    // 静态方法
    static int sum(int a) {
        return a + count;
    }
    
    // 实例方法, 可以访问非静态成员
    int sum2(int a) {
        return currentCount + a + count;
    }
    
    var s1 = Object();
    s1 = StaticClass();
    print((s1 as StaticClass).sum2(10));// 强制类型转换
    // s1 = null;
    print(s1.sum2(10));
    
    if (s1 is StaticClass) {
        print(s1.sum2(10));
        print(s1..currnetCount = 15..sum2(20));// 链式编程, 连续调用. 返回值是对象本身
    }
}

Dart的继承

  • 使用extends继承一个类
  • 子类会继承除了构造方法以外的属性和方法
  • Dart是单继承的
  • 默认继承Object
  • 继承的子类会继承默认构造方法
  • 如果构造方法有参数/有名字, 要主动调用
  • 初始化列表要写在super前面
void extendsDemo() {
    Student st = Student();
    st.run();
    st.sutdy();
    st.name = 'Jack';
    st.age = 18;
    
    print(st.isFree);
    
    Person st1 = Studyent();
    st1.run();
    if (st1 is Student) {
        st1.sutdy();
        st1.age = 17;
        print(st1.isFree);
        print(st1);
    }
}

class Student extends Person {
    final String subName;
    
    Student.withName(String? name) : subName = name!, super.withName(name);
    
    Student() : super.init();
    
     study() {
         print('写作业');
     }
 
     @override
     bool get isFree => age! < 18;
 
     @override
     run() {
         print('学生在跑');
     }
 
     @override
 
}



class Person {
    Person.init();
    
    String? age;
    int? age;
    int? _height;
    bool get isFree => _height! < 120;
    
    run() {
        print('人在跑');
    }
}

Dart的抽象类接口

  • 有点类似协议接口
  • 是不能被实例化的类abstract修饰
  • 继承一个抽象类, 必须要实现里面的抽象方法
abstractDemo() {
    AbstractClass as = SubClass();
    as.sum(10, 20);
    
    SubClass1 sc = SubClass1();
    sc.sum(10, 20);
    sc.sum1(10, 20);
}


abstract class AbstractClass {
    // 抽象方法, 没有实现
    int sum(int a, int b);
}

abstract class AbstractClass1 {
    // 抽象方法, 没有实现
    int sum1(int a, int b);
}

abstract class AbstractClass2 {
    // 抽象方法, 没有实现
    int sum2(int a, int b);
}


class SubClass extends AbstractClass {
    @override
    int sum(int a, int b) {
        print('a + b = ${a + b}');
        return a + b;
    }
}

class SubClass1 implements AbstractClass, AbstractClass1, AbstractClass2 {
    @override
    int sum(int a, int b) {
        print(subClass..sum);
        return 0;
    }
    
    @override
    int sum1(int a, int b) {
        print(subClass..sum1);
        return 0;
    }
    
    @override
    int sum2(int a, int b) {
        print(subClass..sum2);
        return 0;
    }
}

Dart的(多继承)Mixins混入

  • 混入, 类似多继承
  • 作为混入类, 是不能实现构造方法的.
mixinDemo() {
    D d = D();
    d.a();
    d.b();
    d.c();
}

operatorDemo() {
    OperatorClass op1 = OperatorClass(18);
    OperatorClass op2 = OperatorClass(19);
    
    print(op1 > op2);
}

class OperatorClass {
    int age;
    OperatorClass(this.age);
    bool operator >(OperatorClass other) => this.age > other.age;
}

class A {
    a() => print('a....');
}

class B {
    b() => print('b....');
}

class C {
    a() => print('c....'); // 跟A同名的, C在后面, 会覆盖
}



// class D extends A with B, C {}
classD= A with B,C;// 简写


你可能感兴趣的:(跟着测试代码学会Dart2.x的面向对象)