美文网首页
Flutter3-面向对象

Flutter3-面向对象

作者: 镜像 | 来源:发表于2021-12-16 22:02 被阅读0次

    类和对象

    • 使用class关键字声明一个类
    • 可以使用new跟上构造函数
    • 所有的对象都继承Object
    • 声明一个类的成员变量要有默认值,如果没有默认值需要写上?代表可选类型。
    • Dart中默认生成gettersetter方法
    • 属性和方法都通过点语法访问
    • final修饰的属性,必须定义初始值
    • 如果没有赋值初始值,可以在构造函数中添加
    void main() {
      SJPerson person = SJPerson();
      person.name = 'sj';
      person.age = 18;
      person.run();
    }
    
    class SJPerson {
      String? name;
      int? age;
      // SJPerson(this.name);
      void run() {
        print('name:$name, age:$age');
      }
    }
    

    作用域权限

    • 同一份文件中可以随意访问
    • 不同文件中使用_开头的成员变量和方法,不能被外界访问
    // sj_person.dart
    class SJPerson {
      String? _name;
      int? _age;
      // SJPerson(this.name);
      void _run() {
        print('name:$_name, age:$_age');
      }
    
      void initValue(String name, int age) {
        _name = name;
        _age = age;
      }
    
      void printP() {
        _run();
      }
    }
    
    // main.dart
    import 'sj_person.dart';
    
    void main() {
      SJPerson person = SJPerson();
      person.initValue('sj', 18);
      person.printP();
    
      Animal a = Animal();
      a._name = '123';
    }
    
    class Animal {
      String? _name;
    }
    

    构造函数

    类默认有一个构造函数,如果我们自定义了构造函数,默认的构造函数就没有作用了。
    自定义构造函数给成员变量赋值,可以使用this.语法糖直接赋值。

    void main() {
      SJTeacher t = SJTeacher('jx', 30);
    }
    
    class SJTeacher {
      String? name;
      int? age;
      SJTeacher(this.name, this.age);
    }
    

    命名构造函数

    void main() {
      SJPerson person = SJPerson.withName(16);
    }
    
    class SJPerson {
      String? _name;
      int? _age;
      SJPerson(this._name);
    
      SJPerson.withName(this._age);
    }
    

    使用final修饰的好处是,代表这个成员是常量,如果一个类的成员都是final修饰,构造函数前可以加const修饰,这时我们再创建出来的对象就是常量对象,可以节约内存。

    class SJTeacher {
      final String name;
      final int age;
      const SJTeacher(this.name, this.age);
    }
    

    单利

    构造方法正常是不用写返回对象的,如果想返回对象,需要再方法前写上factory,工厂构造方法。

    class FactoryClass {
      static FactoryClass? instance;
    
      factory FactoryClass() {
        if (instance == null) {
          instance = FactoryClass._init();
        }
        return instance!;
      }
      /// 私有的命名构造函数
      FactoryClass._init();
    }
    

    简化如下:

    void main() {
      FactoryClass c1 = FactoryClass();
      FactoryClass c2 = FactoryClass();
      print(c1 == c2);
    }
    
    class FactoryClass {
      static FactoryClass? _instance;
    
      factory FactoryClass() => _instance ??= FactoryClass._init();
    
      /// 私有的命名构造函数
      FactoryClass._init();
    }
    

    初始化列表

    构造函数后面加:,后面的内容就是初始化列表。
    目的:

    1. final变量赋值,它会在初始化之前给列表变量赋值
    2. 校验传递的值,这是最常用也是最主要的功能
    class Person {
      String name;
      int age;
      final height;
      Person(this.name, a, h)
          : height = h,
            age = a,
            assert(h >= 0),
            assert(a > 0) {
        print("hahahhaha");
      }
      Person.init2(this.name, a, h)
          : height = h,
            age = a;
    }
    

    类方法

    • 静态属性、静态方法用类名直接访问。
    • 静态方法不能访问非静态成员。静态方法是类对象调用的,非静态成员是实例对象初始化后才出来的,这时候还没有实例对象,所以不能访问。
    • 实例方法可以直接访问静态属性。实例对象创建时候,静态属性一定在,所以可以访问。
    • 常量属性需要用static修饰
    void staticDemo() {
      StaticClass.count;
      StaticClass.sum(2);
      StaticClass s = StaticClass();
      print(s.sum2(3));
    }
    
    class StaticClass {
      // 静态属性
      static int count = 1;
      int count2 = 2;
    
      static const String name = 'sj';
    
      /// 静态方法
      static sum(int a) {
        return a + count;
      }
    
      int sum2(int a) {
        return a + count + count2;
      }
    }
    

    对象操作符

    var声明变量是动态类型,值可能为null,这时直接执行方法可能会报错,我们把变量后面加个?执行就可以了。

    void dynamicDemo() {
      var s;
      s = StaticClass();
      s.sum2(2);
      s = null;
      s?.sum2(2);
    }
    

    强制类型转换使用as,转换完后面就能用这个转换的类型了。
    使用if判断类型,if里面也可以直接使用此类型。

    void mapDemo() {
      var s = Object();
      s = StaticClass();
      if (s is StaticClass) {
        print(s.sum2(2));
      }
      // print((s as StaticClass).sum2(2));
      // print(s.sum2(2));
    }
    

    使用..链式编程

    void chainedDemo() {
      StaticClass s = StaticClass();
      s..count2 = 10..sum2(2);
    }
    

    继承

    /**
     * Dart中的继承
     * 使用extends继承一个类
     * 子类会继承除了构造方法意外的属性和方法
     * 默认构造方法会自动继承
     * 如果是有参数或者有名字的构造方法,子类需要显性使用super,实现一个即可
     * Dart是单继承
     * 子类重写父类方法使用@override,不写可以,但是不建议
     * super使用可以和初始化列表一起,super要放到最后
     * */
    
    void extendsDemo() {
      S2 s = S2('sj');
      print(s);
    }
    
    class S1 {
      S1.initValue();
      S1(this.age);
      void run() {
        print('run');
      }
    
      int age = 10;
    }
    
    class S2 extends S1 {
      final String name;
      // S2.initValue() : super.initValue();
      S2(String n)
          : name = n,
            super.initValue();
      @override
      void run() {
        // TODO: implement run
        super.run();
      }
    
      // Object的toString方法类似OC的description方法
      @override
      String toString() {
        // TODO: implement toString
        return 'S2 extends S1';
      }
    }
    

    抽象类

    /**
     * 抽象类
     * 不能被实例化的类,使用abstract修饰
     * 子类可以被实例化,子类必须实现父类的抽象方法
     * 多态对象不用判断类型,因为子类必须实现父类的抽象方法
     * 子类可以实现多个抽象类,使用implements,实现需要实现所有方法和属性
     * */
    abstractDemo() {
      SubClass a = SubClass();
      a.sum(10, 20);
    }
    
    abstract class AbstractClass {
      /// 这就是抽象方法
      int sum(int a, int b);
    }
    
    abstract class AbstractClass1 {
      /// 这就是抽象方法
      int minus(int a, int b);
    }
    
    class NormalClass {
      var name;
      void run() {}
    }
    
    class SubClass implements AbstractClass, AbstractClass1, NormalClass {
      @override
      int sum(int a, int b) {
        return a + b;
      }
    
      @override
      int minus(int a, int b) {
        return a - b;
      }
    
      @override
      var name;
    
      @override
      void run() {}
    }
    

    Mixins 混入

    /**
     * 混入
     * 说白了就是多继承
     * 混入如果有一样的方法,会执行最后一个混入的类的方法
     * 作为混入的类,是不能实现构造方法的,且不能继承非Object类
     * */
    mixinsDemo() {
      DClass d = DClass();
      d.a();
      // d.b();
      // d.c();
    }
    
    class AClass {
      AClass();
      a() => print('a ...');
    }
    
    class BClass {
      a() => print('b ...');
    }
    
    class CClass {
      a() => print('c ...');
    }
    
    // class DClass extends AClass with BClass, CClass {}
    
    // 如果DClass没有成员和方法,可简写成下面
    class DClass = AClass with BClass, CClass;
    

    重载操作符

    使用operayor

    operatorDemo() {
      OperatorClass o1 = OperatorClass(18);
      OperatorClass o2 = OperatorClass(15);
      print(o1 > o2);
    }
    
    class OperatorClass {
      int age;
      OperatorClass(this.age);
      bool operator >(OperatorClass o) => this.age > o.age;
    }
    

    相关文章

      网友评论

          本文标题:Flutter3-面向对象

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