首页/文章/flutter

Flutter学习之Dart语言基础(构造函数)

2024-10-25
7053 分钟
...
最常见的构造函数形式,即生成构造函数,创建一个类的新实例:
class Point {
  num x, y; //Dart中int和double是num的子类

  //this引用当前类对象
  Point(num x, num y) {
    this.x = x;
    this.y = y;
  }
}

使用语法糖的时候可以这样定义:

class Point {
  num x, y;

  //用于设置x和y的语法糖
  //在构造函数体运行之前
  Point(this.x, this.y);

  @override
  String toString() {
    return ("x: $x, y: $y");
  }
}

//print(new Point(100, 200)); -> 打印 x: 100, y: 200
默认构造函数

如果未声明构造函数,则会提供默认构造函数。 默认构造函数没有参数,并在调用父类无参数构造函数。

class Parent{
  Parent(){
    print('In Parent\'s constructor.');
  }
}

class Child extends Parent{
  Child(){
    print('In Child\'s constructor.');
  }
}

//new Child(); -> 打印 In Parent's constructor.  In Child's constructor.
构造函数不能继承

子类不能继承其父类构造函数,一个没有声明构造函数的子类只有默认(无参数,无名称)构造函数

命名构造函数

当我们需要定义一个有特别含义的构造函数的时候,可以通过构造函数.XXX来命名构造函数

class Point{
  num x;
  num y;

  Point(this.x, this.y);
  
  //创建一个坐标原点类
  Point.origin(){
    this.x = 0;
    this.y = 0;
  }

 //创建一个坐标为(100, 100)的类
 Point.coordinate100(){
    this.x = 100;
    this.y = 100;
  }
  @override
  String toString() {
    return ("x: $x, y: $y");
  }
}
调用父类构造函数

默认情况下,子类中的构造函数调用父类的未命名无参数构造函数。 父类的构造函数在子类构造函数体的开头被调用。 如果还使用初始化了列表,则会在调用父类构造函数之前执行。 执行顺序如下:

  • 初始化列表
  • 父类的无参数构造函数
  • 子类的无参数构造函数

如果父类没有未命名的无参数构造函数,则必须手动调用父类中的一个构造函数。 在子类的构造函数体之后用冒号(:)指定父类构造函数

例1:默认先调用父类的无参数构造函数

class Parent{
  Parent(){
    print('In Parent\'s constructor.');
  }
}


class Child extends Parent{
  Child(num x, num y) {
    print('In Child\'s constructor.');
  }
}

//new Child(100, 100); -> 打印
//In Parent's constructor.
//In Child's constructor.

例2:手动调用父类其他构造函数

class Parent{
  num x;
  num y;
  Parent(this.x, this.y){
    print('In Parent\'s constructor.');
  }
}

class Child extends Parent{
  Child(num x, num y) : super(x, y){
    print('In Child\'s constructor.');
  }
}

//new Child(100, 100); -> 打印
//In Parent's constructor.
//In Child's constructor.

关于初始化列表:
调用父类构造函数之前,可以在构造函数体执行之前初始化示例变量,用逗号分隔,该过程叫初始化列表。

class Parent{
  num x;
  num y;
  num sum;

  Parent(num px, num py) : x = px, y = py, sum = px + py{
    print("x: $x, y: $y, sum: $sum");
    print('In Parent\'s constructor.');
  }
}

class Child extends Parent{
  Child(num x, num y) : super(x, y){
    print('In Child\'s constructor.');
  }
}

// new Child(100, 100); -> 打印
//x: 100, y: 100, sum: 200
//In Parent's constructor.
//In Child's constructor.
重定向构造函数

有时构造函数需要重定向到同一个类中的另一个构造函数,在冒号后面用this:

class Point {
  num x, y;

  //类的主构造函数
  Point(this.x, this.y);

  //重定向到主构造函数
  Point.alongXAxis(num x) : this(x, 0);
}
常量构造函数

如果你的类需要成为永远不会更改的对象,则可以使这些对象成为编译时常量。 定义const构造函数要确保所有实例变量都是final。

class Point {
  final num x;
  final num y;
  static final Point2 origin = const Point2(0, 0);

  //const关键字放在构造函数名称之前,且不能有函数体
  const Point2(this.x, this.y);
}

没有定义final时提示:

使用函数体时提示:

工厂构造函数

在实现不用总是创建新的类对象的时候,可以使用factory关键字。 例如,工厂构造函数可能从缓存中返回实例,或者它可能返回子类型的实例:

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

  //工厂构造函数无法访问this,所以这里要用static
  //维护一个缓存的Map对象,
  static final Map<String, Logger> _cache =
      <String, Logger>{};
  
 //调用该构造函数的时候,会从Map中取出对象
  factory Logger(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final logger = Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);

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

//调用
var logger = Logger('UI');
logger.log('Button clicked');

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
flutter2026-07-01
Dart 入门回顾
1\. Dart 是什么 Dart 是一门类型安全、支持面向对象、支持异步编程的语言。它的语法和 JavaScript、TypeScript、Java、C# 都有一些相似之处。 Dart 常见使用场景: Flutter 跨平台应用开发 命令行工具 Web 应用 服务端接口或脚本 作为学习现代类型语言的入口 Dart 的几个核心特点: 静态类型:变量、函数返回值、参数都有类型。 类型推断:很多时候可以用 ,让 Dart 自动推断类型。 空...
学习
flutter2026-07-01
Flutter 常用 Widget 入门
Flutter 的核心思想是:一切皆 Widget。文字、图片、按钮、页面结构、布局、间距、滚动、动画、手势,几乎都由 Widget 组合出来。 1\. Widget 先分成几类理解 | 类别 | 常用 Widget | 解决什么问题 | | | | | | 应用入口 | 、 | 搭建应用外壳、主题、路由 | | 页面骨架 | 、 、 | 标准页面结构 | | 基础显示 | 、 、 | 显示文字、图标、图片 | | 布局容器 | 、 、...
学习
flutter2024-11-21
在 Flutter 中使用 webview_flutter 4.0
1. 2. ,已入选 3. 4. 本文是第 4 篇,定位是新手入门,介绍和演示 webview 的基础用法。最后还介绍了事件处理的技巧。因为是补写的,所以本来应该首发的却发在最后了。 环境准备已经在 说过了,不再赘述。既然是新手入门,就会本着详尽的原则,而且会多配示例。 获取页面信息 获取页面 title 核心方法:controller.getTitle 完整示例,放在 main.dart 就能运行。运行示例,点击获取 title 的按...
学习
flutter2024-11-06
flutter android端运行报错Namespace not specified. Specify a namespace in the module‘s build file
在使用flutterSDK 3.24之后发现新建项目,项目默认都是基于AGP8了,由于 AGP 开始强制要求 namespace 配置,不仅仅是主工程,也包括第三方库都强制要求 namespace 。但是我们在引入第三方库的时候会发现部分库没能及时的去做相关配置,这也就导致了我们会出现标题错误: 出现这个问题,我们可能会通过去找到本地缓存的第三方库代码去修改它的build.gradle和AndroidManifest.xml来解决缺失...
学习
flutter2024-11-03
Flutter中如何实现APP升级功能背景
背景 每个App应用中一定会包含的功能 ,App的运行平台不同实现升级功能的方式也就不同,基本分类如下所示。本文主要聚焦在使用Flutter框架开发的应用在安卓系统内如何更新,以及所涉及要点梳理。 IOS系统 Andriod系统 官网下载 各类应用市场 (本文聚焦点) 功能清单(按步骤) UpgradeCard组件(展示升级内容) 进行新旧版本对比判断是否需要更新 下载更新然后安装应用 UpgradeCard组件 组件需要包含基本标题、...
学习
flutter2024-11-03
Flutter应用内更新App版本使用flutter_downloader而非ota_update
做当前App应用内更新的前提:用户可以在App更新的时候还可以使用软件,不能让他一直等待下载,关闭下载组件后,打开组件还能继续看到他的进度,并且用户锁屏或者短暂退出APP后需要保证任务不能总是挂掉,这里没有用到保活,而是需要用到生命周期去让他暂停和恢复,所以当前app还要有一个全局管理类保存任务id。UI图在最后 (插件文档说明可以通知栏显示,但是我用的这个版本在100%下完后总是failed,而不是complete,就不会很友好,后面...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录