text: (window.webpackJsonp=window.webpackJsonp||[]).push([[32],{394:function(n,t,a){"use strict";a.r(t);var e=a(42),s=Object(e.a)({},(function(){var n=this,t=n.$createElement,a=n._self._c||t;return a("ContentSlotsDistributor",{attrs:{"slot-key":n.$parent.slotKey}},[a("h1",{attrs:{id:"dart-类"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#dart-类"}},[n._v("#")]),n._v(" Dart-类 😕")]),n._v(" "),a("p",[n._v("参考：Dart官网")]),n._v(" "),a("h3",{attrs:{id:"构造函数"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#构造函数"}},[n._v("#")]),n._v(" 构造函数 😃")]),n._v(" "),a("p",[n._v("构造函数名字可以为 "),a("code",[n._v("ClassName")]),n._v(" 或者 "),a("code",[n._v("ClassName.identifier")])]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  var jsonData = JSON.decode('{\"x\":1, \"y\":2}');\n    \n  class Point {\n    num x;\n    num y;\n\n    // 通过 ClassName定义构造函数\n    // Point(num x, num y) {\n    //   this.x = x;\n    //   this.y = y;\n    // }\n\n    // 或者 精简方法\n    Point(this.x, this.y);\n\n    // 通过ClassName.identifier定义构造函数\n    Point.fromJson(Map json) {\n      x = json['x'];\n      y = json['y'];\n    }\n  }\n  \n  // 直接创建Point类\n  var p1 = new Point(2, 2);\n\n  // 通过Json创建Point类\n  var p2 = new Point.fromJson(jsonData);\n")])])]),a("h3",{attrs:{id:"构造函数不能继承"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#构造函数不能继承"}},[n._v("#")]),n._v(" 构造函数不能继承 😮")]),n._v(" "),a("p",[n._v("构造函数不能继承，所以超类的命名构造函数 也不会被继承。如果你希望 子类也有超类一样的命名构造函数， 你必须在子类中自己实现该构造函数。")]),n._v(" "),a("p",[n._v("如果超类没有无名无参数构造函数， 则你需要手工的调用超类的其他构造函数。 在构造函数参数后使用冒号 : 可以调用 超类构造函数。")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  class Person {\n    String firstName;\n\n    Person.fromJson(Map data) {\n      print('in Person');\n    }\n  }\n\n  class Employee extends Person {\n    \n    // Person没有默认的构造函数;\n    // 必须 call super.fromJson(data).\n\n    Employee.fromJson(Map data) : super.fromJson(data) {\n      print('in Employee');\n    }\n  }\n\n  main() {\n    var emp = new Employee.fromJson({});\n\n    // emp 是 Person\n    // emp 是 Employee\n    if (emp is Person) {\n      emp.firstName = 'Bob';\n    }\n    (emp as Person).firstName = 'Bob';\n  }\n")])])]),a("h3",{attrs:{id:"构造函数执行顺序"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#构造函数执行顺序"}},[n._v("#")]),n._v(" 构造函数执行顺序 😕")]),n._v(" "),a("ol",[a("li",[n._v("初始化参数列表")]),n._v(" "),a("li",[n._v("超类的无名构造函数")]),n._v(" "),a("li",[n._v("主类的无名构造函数")])]),n._v(" "),a("h3",{attrs:{id:"初始化列表"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#初始化列表"}},[n._v("#")]),n._v(" 初始化列表 😃")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  class Point {\n    num x;\n    num y;\n\n    Point(this.x, this.y);\n\n    Point.fromJson(Map jsonMap)\n        : x = jsonMap['x'],\n          y = jsonMap['y'] {\n      print('In Point.fromJson(): ($x, $y)');\n    }\n  }\n")])])]),a("p",[n._v("注意：初始化表达式等号右边的部分"),a("code",[n._v("不能访问 this")]),n._v("。")]),n._v(" "),a("p",[n._v("初始化列表非常适合用来设置 "),a("code",[n._v("final")]),n._v(" 变量的值。")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  import 'dart:math';\n\n  class Point {\n    final num x;\n    final num y;\n    final num distanceFromOrigin;\n\n    Point(x, y)\n        : x = x,\n          y = y,\n          distanceFromOrigin = sqrt(x * x + y * y);\n  }\n\n")])])]),a("h3",{attrs:{id:"重定向构造函数"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#重定向构造函数"}},[n._v("#")]),n._v(" 重定向构造函数 😮")]),n._v(" "),a("p",[n._v("一个重定向构造函数是没有代码的，在构造函数声明后，使用"),a("code",[n._v(":")]),n._v("调用其他构造函数。")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  class Point {\n    num x;\n    num y;\n\n    Point(this.x, this.y);\n\n    // 重定向\n    Point.alongXAxis(num x) : this(x, 0);\n  }\n")])])]),a("h3",{attrs:{id:"编译时常量"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#编译时常量"}},[n._v("#")]),n._v(" 编译时常量 😦")]),n._v(" "),a("p",[n._v("两个一样的编译时常量其实是 同一个对象：")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  var a = const ImmutablePoint(1, 1);\n  var b = const ImmutablePoint(1, 1);\n\n  assert(identical(a, b)); // They are the same instance!\n")])])]),a("h3",{attrs:{id:"常量构造函数"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#常量构造函数"}},[n._v("#")]),n._v(" 常量构造函数 😐")]),n._v(" "),a("p",[n._v("如果你的类提供一个状态不变的对象，你可以把这些对象 定义为编译时常量。要实现这个功能，需要定义一个 "),a("code",[n._v("const")]),n._v(" 构造函数， 并且声明所有类的变量为 "),a("code",[n._v("final")]),n._v("。")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  class ImmutablePoint {\n    final num x;\n    final num y;\n    const ImmutablePoint(this.x, this.y);\n    static final ImmutablePoint origin =\n        const ImmutablePoint(0, 0);\n  }\n")])])]),a("h3",{attrs:{id:"工厂方法构造函数"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#工厂方法构造函数"}},[n._v("#")]),n._v(" 工厂方法构造函数 😃")]),n._v(" "),a("p",[n._v("如果一个构造函数并不总是返回一个新的对象，则使用 "),a("code",[n._v("factory")]),n._v(" 来定义 这个构造函数。("),a("strong",[n._v("工厂构造函数无法访问 this。")]),n._v(")")]),n._v(" "),a("p",[n._v("下面代码演示工厂构造函数 如何从缓存中返回对象。")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  class Logger {\n    final String name;\n    bool mute = false;\n\n    // 缓存池\n    static final Map<String, Logger> _cache =\n        <String, Logger>{};\n\n    // 工厂函数\n    factory Logger(String name) {\n      if (_cache.containsKey(name)) {\n        return _cache[name];\n      } else {\n        final logger = new Logger._internal(name);\n        _cache[name] = logger;\n        return logger;\n      }\n    }\n    \n    Logger._internal(this.name);\n\n    void log(String msg) {\n      if (!mute) {\n        print(msg);\n      }\n    }\n  }\n")])])]),a("h3",{attrs:{id:"抽象类"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#抽象类"}},[n._v("#")]),n._v(" 抽象类 😐")]),n._v(" "),a("p",[n._v("抽象类：一个"),a("strong",[n._v("不能被实例化")]),n._v("的类，使用 "),a("code",[n._v("abstract")]),n._v(" 修饰符定义。（在Flutter中用的挺多的。）")]),n._v(" "),a("p",[n._v("抽象类通常用来定义接口， 以及部分实现。如果你希望你的抽象类 是可示例化的，则定义一个 工厂 构造函数。")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  // 抽象类 - 不能被实例化\n  abstract class AbstractContainer {\n    // ...Define constructors, fields, methods...\n\n    void updateChildren(); // 抽象函数\n\n    void myPrint() {\n      print('一个普通函数');\n    }\n  }\n")])])]),a("h3",{attrs:{id:"隐式接口"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#隐式接口"}},[n._v("#")]),n._v(" 隐式接口 😮")]),n._v(" "),a("p",[n._v("每个类都隐式的定义了一个包含所有实例成员的接口，并且这个类实现了这个接口。如果你想 创建类 A 来支持 类 B 的 api，而不想继承 B 的实现， 则类 A 应该实现 B 的接口。")]),n._v(" "),a("p",[n._v("一个类可以通过 "),a("code",[n._v("implements")]),n._v(" 关键字来实现一个或者多个接口， 并实现每个接口定义的 API。")]),n._v(" "),a("p",[n._v("通俗的讲：使用"),a("code",[n._v("implements")]),a("strong",[n._v("就意味着要重写接口的API")])]),n._v(" "),a("p",[n._v("使用场景：比如Flutter的"),a("code",[n._v("Provider")]),n._v("以接口来实现"),a("code",[n._v("dispose")]),n._v("的重写操作")]),n._v(" "),a("p",[a("code",[n._v("-_-!")]),n._v(" 比起抽象函数，接口重写的更多，但是提供接口方是可以被实例化的。")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  class Point implements Comparable, Location {\n    // ...\n  }\n")])])]),a("h3",{attrs:{id:"继承"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#继承"}},[n._v("#")]),n._v(" 继承 😃")]),n._v(" "),a("p",[n._v("继承是最基础的啦（基本上大家都懂，就Mark一下）")]),n._v(" "),a("p",[n._v("Dart的继承使用 "),a("code",[n._v("extends")]),n._v(" 定义子类， "),a("code",[n._v("supper")]),n._v(" 引用 超类。子类可以覆写父类的函数，（可加"),a("code",[n._v("@override")]),n._v("注解，来表示你的函数想覆盖父类函数）")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  class Television {\n    void turnOn() {\n      _illuminateDisplay();\n      _activateIrSensor();\n    }\n    // ...\n  }\n\n  class SmartTelevision extends Television {\n    void turnOn() {\n      super.turnOn();\n      _bootNetworkInterface();\n      _initializeMemory();\n      _upgradeApps();\n    }\n    // ...\n  }\n")])])]),a("h3",{attrs:{id:"mixin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mixin"}},[n._v("#")]),n._v(" mixin")]),n._v(" "),a("p",[n._v("mixin：提供了一种多继承机制，使用和class类似，只不过没有构造方法。")]),n._v(" "),a("p",[n._v("通过"),a("code",[n._v("on")]),n._v("关键字可以限定mixin允许被哪些类使用，除非希望mixin可以像普通类一样使用，否则使用"),a("code",[n._v("mixin")]),n._v("关键字而不是"),a("code",[n._v("class")]),n._v("。")]),n._v(" "),a("p",[n._v("在mixin中，后"),a("code",[n._v("with")]),n._v("的函数会覆盖前面的函数。")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  mixin Dog on Animal{\n    bool isDog = true;\n\n    void eat() {\n      // ...\n    }\n  }\n\n  mixin Cat {\n    // ...\n  }\n\n  class A extends Animal with Dog, Cat {\n    // ...\n  }\n")])])]),a("h3",{attrs:{id:"函数"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#函数"}},[n._v("#")]),n._v(" 函数 😐")]),n._v(" "),a("p",[n._v("类中可以定义函数，函数大部分用法和JS类似")]),n._v(" "),a("p",[n._v("可以通过实行 "),a("code",[n._v("getter")]),n._v(" 和 "),a("code",[n._v("setter")]),n._v(" 来创建新的属性")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  class Rectangle {\n    num left;\n    num top;\n    num width;\n    num height;\n\n    Rectangle(this.left, this.top, this.width, this.height);\n\n    num get right             => left + width;\n        set right(num value)  => left = value - width;\n    num get bottom            => top + height;\n        set bottom(num value) => top = value - height;\n  }\n")])])]),a("p",[n._v("抽象函数：没有函数体的函数，抽象类和非抽象类都可以定义抽象函数。")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  abstract class Doer {\n    \n    // 抽象函数\n    void doSomething(); \n  }\n\n  class EffectiveDoer extends Doer {\n\n    // 重写\n    void doSomething() {\n      // some...\n    }\n  }\n")])])]),a("p",[n._v("可以通过"),a("code",[n._v("operator")]),n._v("来复写操作符")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v("  class Vector {\n    final int x;\n    final int y;\n    const Vector(this.x, this.y);\n\n    // 重写 +\n    Vector operator +(Vector v) {\n      return new Vector(x + v.x, y + v.y);\n    }\n\n    // 重写 -\n    Vector operator -(Vector v) {\n      return new Vector(x - v.x, y - v.y);\n    }\n  }\n")])])]),a("h3",{attrs:{id:"静态变量-函数"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#静态变量-函数"}},[n._v("#")]),n._v(" 静态变量/函数 😃")]),n._v(" "),a("p",[n._v("使用 static 关键字来实现类级别的 静态变量和函数。")]),n._v(" "),a("p",[n._v("不同点")]),n._v(" "),a("ul",[a("li",[n._v("可以不用new，直接执行。"),a("code",[n._v("Point.distanceBetween(a, b)")])]),n._v(" "),a("li",[n._v("静态变量在第一次使用的时候才被初始化。")]),n._v(" "),a("li",[n._v("静态函数不再类实例上执行，(所以无法访问 "),a("code",[n._v("this")]),n._v(")")])]),n._v(" "),a("h3",{attrs:{id:"call"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#call"}},[n._v("#")]),n._v(" call()")]),n._v(" "),a("p",[n._v("如果 Dart 类实现了 "),a("code",[n._v("call()")]),n._v(" 函数则 可以当做方法来调用。")]),n._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[n._v('  class ClassFunction {\n  call(String a, String b, String c) => \'$a $b $c!\';\n}\n\nmain() {\n  var cf = new ClassFunction();\n    var out = cf("wangxiaojian","is","talent");\n    print(\'$out\');\n    print(cf.runtimeType);\n    print(out.runtimeType);\n    print(cf is Function);\n  }\n  \n  // 运行结果：\n  // wangxiaojian is talent!\n  // ClassFunction\n  // String\n  // false\n')])])]),a("h3",{attrs:{id:"end"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#end"}},[n._v("#")]),n._v(" End 😦")]),n._v(" "),a("p",[n._v("结束啦")])])}),[],!1,null,null,null);t.default=s.exports}}]);