Flutter Dart类

目录

构造函数

命名构造函数

重定向构造函数

常量构造函数

工厂构造函数

Getters 和 Setters

初始化列表

可覆写的操作符


        创建一个dart文件,名称全小写,里面的类可以按照驼峰命名法。文件名和类名可以不保持统一,这个跟Java有明显区别。

        Dart是一种面向对象的语言,具有类和基于mixin的继承。每个对象都是一个类的实例,所有的类都是Object的子类。基于mixin的继承意味着,尽管每个类(除了Object)都只有一个超类,但类主体可以在多个类层次结构中重用

        示例中向你展示了一个包含2个属性、2个构造函数以及1个函数的类。

//每个实例变量都会自动生成一个 getter 方法(隐含的)。 非final 实例变量还会自动生成一个 setter 方法。

class SccPoint{
  late num x;
  num y;
  //构造函数
  SccPoint(this.x,this.y);

  //命名构造函数
  //Dart 不支持构造函数的重载
  SccPoint.y(this.y){
    x = 0;
  }
  //函数
  void position(){
    print("x=$x,y=$y");
  }
}

构造函数

        由于把构造函数参数赋值给实例变量的场景太常见了, Dart 提供了一个语法糖来简化这个操作:

  //构造函数
  SccPoint(this.x,this.y);

命名构造函数

        Dart 不支持构造函数的重载,而采用了命名构造函数为一个类实现多个构造函数:

  //命名构造函数
  //Dart 不支持构造函数的重载
  SccPoint.y(this.y){
    x = 0;
  }

「运行结果」

重定向构造函数

        有时候一个构造函数会调动类中的其他构造函数(在Java中就是 this(...))。 一个重定向构造函数是没有代码的,在构造函数声明后,使用 冒号调用其他构造函数。

class SccPoint{
  num x;
  num y;
  //构造函数
  SccPoint(this.x,this.y);

  //命名构造函数
  SccPoint.y(num y):this(0,y);//调用上面的构造函数

}

常量构造函数

        如果你的类提供一个状态不变的对象,你可以把这些对象 定义为编译时常量。要实现这个功能,需要定义一个 const 构造函数, 并且声明所有类的变量为 final

class ImmutablePoint {
  final num x;
  final num y;
  //常量构造函数
  const ImmutablePoint(this.x, this.y);
}

void main(){
  //构造两个相同的编译时常量会生成一个单一的、规范的实例
  var p3 = const ImmutablePoint(1,2);
  var p4 = const ImmutablePoint(1,2);
  print(p3 == p4); // true
  print(identical(p3, p4));// true
}

工厂构造函数

        当实现一个使用 factory 关键词修饰的构造函数时,这个构造函数不必创建类的新实例。例如,一个工厂构造函数 可能从缓存中获取一个实例并返回,或者 返回一个子类型的实例。(工厂构造函数无法访问 this

class Logger {
  final String name;
  bool mute = false;

  // _cache 变量是库私有的,因为在其名字前面有下划线。
  static final Map<String, Logger> _cache =
  <String, Logger>{};

  factory Logger(String name) {
    return _cache.putIfAbsent(
        name, () => Logger._internal(name)); //工厂构造函数里可以调用其他构造函数。
  }

  factory Logger.fromJson(Map<String, Object> json) {
    return Logger(json['name'].toString());
  }
  //以 _ 开头的函数是库私有的,无法在库外使用
  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) print(msg);
  }
}

        借助工厂构造函数能够实现单例:

//使用工厂构造实现单例
class Manager {
  static final Manager _singleton = Manager._internal();

  factory Manager() {
    return _singleton;
  }
  Manager._internal();
}

//使用
  var m1 = Manager();
  var m2 = Manager();
  print(m1 == m2); // true

Getters 和 Setters

        Dart中每个实例变量都隐含的具有一个 getter, 如果变量不是 final 的则还有一个 setter。可以通过实现 getter 和 setter 来创建新的属性, 使用 getset 关键字定义 getter 和 setter:

class SccPoint{
  num x;
  num y;
  SccPoint(this.x,this.y);
  void position(){
    print("x=$x,y=$y,a=$a");
  }
  //使用 get定义了一个 a 属性(不可与原属性同名)
  num get a   => x+y;
  set a(num b) => x=x+b;
}

void main() {
  var p9 = SccPoint(3, 9);
  p9.position();//x=3,y=9,a=12
  p9.a=10;
  p9.position();//x=13,y=9,a=22
}
 

注意:在get与set中使用自身会导致Stack Overflow(递归)

调用自身:

初始化列表

        在构造函数函数体执行之前会首先执行初始化列表,非常适合用来设置 final 变量的值。

class SccPoint{
  num? x;
  num? y;
  SccPoint.fromJson(Map<String, num> json)
      : x = json['x'],
        y = json['y'] {
    print('In SccPoint.fromJson(): ($x, $y)');
  }

}

  //使用
  SccPoint.fromJson({"x":15,"y":20});

可覆写的操作符

        把已经定义的、有一定功能的操作符进行重新定义。可以重新定义的操作符有:

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

        比如:dart.math包下Point类就重写了 +、-、*、==这几个操作符。

  Point<T> operator +(Point<T> other) {
    return Point<T>((x + other.x) as T, (y + other.y) as T);
  }
  Point<T> operator *(num /*T|int*/ factor) {
    return Point<T>((x * factor) as T, (y * factor) as T);
  }

        操作符重载函数的名字是“关键字 operator +以及紧跟其后的一个 Dart 预定义的操作符。

class SccPoint{
  num x;
  num y;
  SccPoint(this.x,this.y);
  //加
  SccPoint operator +(SccPoint point){
    return SccPoint(x+point.x,y+point.y);
  }
  //乘
  SccPoint operator *(SccPoint point){
    return SccPoint(x*point.x,y*point.y);
  }
  void position(){
    print("x=$x,y=$y");
  }
}

使用

//导入类文件(最好全路径),看起来直观一些
import 'package:flutter_demo_scc/scc_point.dart';

//导入类文件(相对路径),两种都可以
// import 'scc_point.dart';

void main() {
  var p5 = SccPoint(3, 5);
  var p6 = SccPoint(2, 7);
  var p7 = p5+p6;
  var p8 = p5*p6;
  p5.position();//x=3,y=5
  p6.position();//x=2,y=7
  p7.position();//x=5,y=12
  p8.position();//x=6,y=35
}

猜你喜欢

转载自blog.csdn.net/g984160547/article/details/131382715