Dart 基础知识(三)

文档地址

      类与对象

        使用 关键字 class 声明一个类;

        使用 关键字 new 创建一个对象, new 可以省略;

        所有对象都继承于 Object 类

      构造方法

        如果没有自定义构造方法,则会有个默认构造 方法, 并且该构造函数会 调用其父类 的无参数构造方法;

        如果存在自定义构造方法,则 默认构造方法无效;

        构造方法不能重载(不能存在同名的构造方法);

        子类不会继承父类的构造函数,如果子类没有声明构造函数,那么只会有一个默认无参数的构造函数。

            注意: 所有未初始化的实例变量其值均为 null

  构造方法 语法糖

        使用 命名构造方法,可以实现多个构造方法;

              使用 类名. 方法 的形式实现

类名. 方法

    常量构造函数

        一些类提供了 常量构造函数。使用常量构造函数,在构造函数名之前加 const 关键字,来创建编译时常量时,两个使用 相同构造函数 相同参数值 构造的编译时常量是同一个对象:

常量构造函数

    计算属性

        计算属性的值是通过计算而来,本身不存储值;

        计算属性赋值,其实是通过计算转换到其他实例变量;

    计算属性

    调用父类非默认构造函数

        子类的构造函数会调用父类的匿名无参数构造方法,并且该调用会在子类构造函数的函数体代码执行前,如果子类构造函数还有一个 初始化列表,那么该初始化列表会在调用父类的该构造函数之前被执行,总的来说,这三者的调用顺序如下(重要):

        1 初始化列表;

        2 父类的无参数构造函数;

        3 当前类的构造函数;

        如果 父类没有匿名无参数构造函数,那么子类必须调用父类的其中一个构造函数,为子类的构造函数 指定一个父类的构造函数 只需在构造函数体前使用(:)指定。

    初始化列表

           除了 调用父类构造函数 之外,还可以在 构造函数体执行之前 初始化实例变量。每个实例变量之间使用 逗号 分隔;

          注意:初始化列表会在构造方法体执行 之前 执行,初始化列表表达式 = 右边的语句 不能使用 this 关键字

          初始化列表常 用于设置 final 变量的值 (跟语法糖作用一样);

 初始化列表

    重定向构造函数

        有时候类中的构造函数仅用于 调用类中其它的构造函数,此时该构造函数没有函数体,只需在函数签名后使用(:)指定需要重定向到的其它构造函数 (使用 this 而非类名):

    重定向构造函数

    常量构造函数

        如果类生成的对象都是不变的,可以在生成这些对象时就将其变为编译时常量。你可以在类的构造函数前加上 const 关键字并确保所有 实例变量 均为 final 来实现该功能;

   常量构造方法

    工厂构造函数

        工厂构造方法类似于设计模式中的工厂模式;

        在构造方法前添加 关键字 factory 实现 一个工厂构造方法,这将意味着使用该构造函数构造类的实例时 并非总是会返回 新的实例对象

        例如,工厂构造函数可能会从缓存中返回一个实例,或者返回一个子类型的实例;

        在工厂构造方法中 可返回对象;

        注意: 在工厂构造函数中无法访问 this!

         Logger 的工厂构造函数从缓存中返回对象,和 Logger.fromJson 工厂构造函数从 JSON 对象中初始化一个最终变量;

工厂构造函数

    静态成员

         使用 关键字 static 来实现 类级别 的变量和函数;

        静态成员 不能访问 非静态成员,非静态成员可以访问静态成员

        1. 静态变量

            静态变量(即类变量)常用于声明类范围内所属的状态变量和常量:

            类中的常量需要使用 static const 声明;

静态变量

        2. 静态方法

            静态方法(即类方法)不能对实例进行操作,因此 不能使用 this。但是他们可以访问静态变量;

静态方法

    对象操作符

         条件成员访问:?.    // ?前面不为空就接着执行, 为空就不执行. 后面得

         类型转换 : as

         是否指定类型: is , is!  // 有点像 instanceof

         级联模式: ..

 级联模式

    操作符复写(运算符的重载)

        复写操作符需要在类中定义

            返回类型 operator 操作符 (参数1, 参数2, ....){

              // 实现code

              return 返回值

            }

操作符复写

        注意:如果覆写 ==, 还需要覆写对象的 hashCode getter 方法;

        可覆写的操作符

            < 、+、|、[]、>、/、^、[]=、 <=、~/、&、~、>=、*、<<、==、-、%、>>


        对象 call 方法 (还是不建议使用)

            如果类实现了 call() 方法 , 则 该类的对象 可以作为 方法 使用;

对象 call 方法 

    Getter 和 Setter

        Getter 和 Setter 是一对用来读写对象属性的特殊方法,上面说过实例对象的每一个属性都有一个隐式的 Getter 方法,如果为非 final 属性的话还会有一个 Setter 方法,你可以使用 get 和 set 关键字为额外的属性添加 Getter 和 Setter 方法:

Getter 和 Setter

面向对象扩展

    继承

        使用 关键字 extends 继承一个类,并可使用 关键字 super 引用一个父类;

        子类会继承父类可见的属性 和方法,不会继承构造方法

         子类可以重写父类的实例方法(包括操作符)、 Getter 以及 Setter 方法。你可以使用 @override 注解来表示你重写了一个成员;

          单继承, 多态性

extends

抽象类(像其他语言的接口)

        抽象类使用 关键字 abstract 表示 ,不能直接被实例化;

        抽象方法不用 abstract 装饰, 无实现;

        抽象类 可以 没有抽象方法

        有抽象方法的类一定得声明为抽象类

        抽象类常用于声明接口方法(重要)、有时也会有具体的方法实现;

  抽象类

 接口 (和其他语言接口不同)

    类和接口是统一的, 类就是接口;

    每个类都隐式的定义了一个包含所有实例成员的接口;

    如果是复用已有类的实现,使用继承(extends) (因为接口都是要重写属性和方法);

    如果只是使用已有类得外在行为,使用接口(implements);

    如果需要实现多个类接口,可以使用逗号分割每个接口类:

           class Point implements Comparable, Location {...}

implements

    注意推荐 使用 抽象类的形式作为接口;

Mixin (重要)

   1 Mixins 类似于多继承, 是在多类继承中重用一个类代码的方式;

        使用 with 关键字并在其后跟上 Mixin 类的名字来使用 Mixin 模式:

   2 作为 Mixin的类 不能有显示声明构造方法, 比如:

不能有显示声明构造方法

  3 作为 Mixin 的类,只能继承子 Object, 比如 A,B, C 不能extends 其他类

  4 使用关键字 with 连接 一个或多个 mixin

     A,B,C,D 四个类

    class D extends A with B, C { }

    简写 class D = A with B , C, 此写法适合 D 中没有自己的属性和方法

    如果方法 A, B, C 中方法同名,调用最后一个继承的 方法,上面就是 调用C中的方法;

Mixin

    注意:请记住 想要实现一个 Mixin,请创建一个继承自 Object 且 未声明构造函数的类!


枚举类型

    index 从0 开始, 依次累加

    不能指定原始值;

    不能添加方法;

    枚举不能成为子类,也不可以 mix in,你也不可以实现一个枚举;

    不能显式地实例化一个枚举类;

    每一个枚举值都有一个名为 index 成员变量的 Getter 方法

    enum Color { red, green, blue }

    assert(Color.red.index == 0);                                                                                      

    assert(Color.green.index == 1); 

    assert(Color.blue.index == 2);

    使用枚举类的 values 方法获取全部的枚举值

        List colors = Color.values;

        assert(colors[2] == Color.blue);


泛型

    泛型的作用

        泛型常用于需要要求类型安全的情况,但是它也会对代码运行有好处:

            1. 适当地指定泛型可以更好地帮助代码生成;

            2. 使用泛型可以减少代码重复

    泛型的使用

           1 泛型类

类的泛型

           2 泛型方法

                方法 first 的泛型 T 可以在如下地方使用:

                    函数的返回值类型 (T);

                    参数的类型 (List);

                    局部变量的类型 (T tmp);

方法的泛型

限制参数化类型

    子类限制继承 Object :

限制参数化类型

    规定了要使用 SomeBaseClass 或者它的子类来作为泛型参数:

限制参数化类型

你可能感兴趣的:(Dart 基础知识(三))