当前位置:首页 > 后端开发 > 正文内容

Flutter/Dart第15天:Dart类结构函数

邻居的猫1个月前 (12-09)后端开发214

Dart官方文档:https://dart.dev/language/constructors

重要说明:本博客依据Dart官网文档,但并不是简略的对官网进行翻译,在掩盖中心功用情况下,我会依据个人研制经历,参加自己的一些扩展问题和场景验证。

如下代码样例,和Java相似,最常用的生成式结构函数:

class Point {
  double x = 0;
  double y = 0;

  Point(double x, double y) {
    this.x = x;
    this.y = y;
  }
}

最佳实战:在Dart中,仅当命名抵触时,才运用this关键字,不然一般能够省掉this关键字。

初始化参数列表

如上最常用的结构函数,Dart能够进一步优化如下初始化参数方式。一同,也能够为非空变量设置默许值。

class Point {
  final double x;
  final double y;

  // 在结构函数体履行之前,初始化实例变量
  Point(this.x, this.y);
}

默许结构函数

和Java相似,类假如没有声明结构函数,那么它会有个默许的结构函数。默许结构函数没有入参,它只会调用父类的没有入参的结构函数。

结构函数无法承继

子类无法承继父类的结构函数,假如子类没有声明结构函数,那么这个子类就只有默许结构函数(不管父类是否有其他结构函数)。

命名结构函数

在Dart中,经过命名结构函数,能够为类供给多个结构函数,并且在创立目标时愈加明晰。

const double xOrigin = 0;
const double yOrigin = 0;

class Point {
  final double x;
  final double y;

  Point(this.x, this.y);

  // `origin`命名结构函数
  Point.origin()
      : x = xOrigin,
        y = yOrigin;
}

特别注意:如上节说到,子类无法承继父类的结构函数,包含父类的命名结构函数。假如子类想运用父类的某个命名结构函数,那么子类有必要完成该命名结构函数。

调用父类结构函数

默许情况下,子类无入参的非命名结构函数会调用父类的无入参的非命名结构函数。父类的结构函数在结构函数体之前被调用。假如有初始化参数列表,那么初始化参数列表在父类结构函数调用之前被调用。

结构函数相关的调用次序如下:

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

特别注意:假如父类没有经过无入参且非命名的结构函数,那么咱们有必要手艺调用父类的一个结构函数,经过冒号:后边紧跟父类结构函数。

如下代码样例,Person是父类,它仅声明晰一个命名结构参数。Employee是承继Person的子类,由于父类没有声明无入参非命名的结构函数,因而在它结构函数都有必要手艺调用父类的某个结构函数。如命名结构函数fromJson后边,经过冒号:调用了父类的命名结构函数。

// 未声明:无入参、非命名的结构函数
class Person {
  String? firstName;

  Person.fromJson(Map data) {
    print('in Person');
  }
}

class Employee extends Person {
  // 手艺调用父类的结构函数:super.fromJson()
  Employee.fromJson(super.data) : super.fromJson() {
    print('in Employee');
  }
}

void main() {
  var employee = Employee.fromJson({});
  print(employee);
  // 成果:
  // in Person
  // in Employee
  // Instance of 'Employee'
}

特别注意:由于结构函数参数是在调用结构函数之前核算,因而结构函数的参数能够是表达式,如函数调用等。父类的结构函数不能运用this.关键字,由于参数能够是表达式、静态函数等,并不一定是类实例。

class Employee extends Person {
  Employee() : super.fromJson(fetchDefaultData());
  // ···
}

手艺调用父类的结构函数,然后逐个设置入参比较繁琐,假如咱们想要简化,那么能够父类的初始值结构函数。这个功用不能与重定向结构函数一同运用(由于语法抵触)。

class Vector2d {
  final double x;
  final double y;

  Vector2d(this.x, this.y);
}

class Vector3d extends Vector2d {
  final double z;

  // 默许情况下,咱们的运用方法:
  // Vector3d(final double x, final double y, this.z) : super(x, y);
  
  // 简化版别:
  Vector3d(super.x, super.y, this.z);
}

如下代码样例,父类的初始化结构函数能够经过命名参数调用。

class Vector2d {
  // ...

  Vector2d.named({required this.x, required this.y});
}

class Vector3d extends Vector2d {
  // ...

  Vector3d.yzPlane({required super.y, required this.z}) : super.named(x: 0);

  // 等价调用
  // Vector3d.yzPlane({required double y, required this.z}) : super.named(x: 0, y: y);
}

初始化列表

在结构函数履行之前,咱们能够调用父类的结构函数,还能够初始化实例变量。实例变量初始化经过逗号分隔。

Point.fromJson(Map<String, double> json)
    : x = json['x']!,
      y = json['y']! {
  print('In Point.fromJson(): ($x, $y)');
}

开发阶段,咱们能够在初始化列表中添加断语:

Point.withAssert(this.x, this.y) : assert(x >= 0) {
  print('In Point.withAssert(): ($x, $y)');
}

初始化列表在设置final不行变量时十分有用:

import 'dart:math';

class Point {
  final double x;
  final double y;
  final double distanceFromOrigin;

  Point(double x, double y)
      : x = x,
        y = y,
        distanceFromOrigin = sqrt(x * x + y * y);
}

void main() {
  var p = Point(2, 3);
  print(p.distanceFromOrigin);
  // 输出:3.605551275463989
}

重定向结构函数

重定向结构函数,便是运用类的其他的结构函数,重定向到的结构函数运用this关键字:

class Point {
  double x, y;

  // 主结构函数
  Point(this.x, this.y);

  // 重定向到主结构函数
  Point.alongXAxis(double x) : this(x, 0);
}

常量结构函数

假如目标的数据不会改动,这些目标能够作为编译期常量。

常量结构函数要求:实例变量都是final不行变量,界说一个const修饰符的结构函数。

特别注意:上一文咱们有说到常量结构函数,常量结构函数创立的目标并不一定<?都是常量(当创立的目标没有const修饰符,或许目标不是在const常量上下文中,那么该目标就不是常量)!

如下代码样例,ImmutablePoint有常量结构函数,它创立的3个目标中,前面2个是常量,后边1个并十分量。

class ImmutablePoint {
  static const ImmutablePoint origin = ImmutablePoint(0, 0);

  final double x, y;

  const ImmutablePoint(this.x, this.y);
}

// `a`和`b`目标是常量,且它们归于同一个实例
var a = const ImmutablePoint(1, 2);
var b = const ImmutablePoint(1, 2);

assert(identical(a, b));

// `c`目标并十分量,它也和`a`或许`b`不是同一个实例
var c = ImmutablePoint(1, 2);
assert(!identical(a, b));

工厂结构函数

在一个不总是创立实例的类中,运用factory关键字完成一个结构函数,即为工厂结构函数。

工厂结构函数常用运用场景:如经过结构函数,从缓存获取目标,或许创立其子类,或许创立不行变常量可是又不想供给初始化参数列表等。

如下代码样例,Logger工厂结构函数优先从缓存获取目标,而Logger.fromJson()工厂结构函数则初始化了一个final不行实例变量:

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

  static final Map<String, Logger> _cache = <String, Logger>{};

  // 优先从缓存获取目标,假如不存在则新增
  factory Logger(String name) {
    print('默许结构函数:$name');
    return _cache.putIfAbsent(name, () => Logger._internal(name));
  }

  // 命名结构函数,经过工厂结构函数获取目标(缓存,或新增)
  factory Logger.fromJson(Map<String, Object> json) {
    print('命名结构函数:$json');
    return Logger(json['name'].toString());
  }

  Logger._internal(this.name);

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

工厂结构函数的运用,和一般结构函数无本质区别:

var logger = Logger('UI');
logger.log('Hi NTopicCN.');
// 成果:
// 默许结构函数:UI
// Hi NTopicCN.

var loggerJson = Logger.fromJson({'name': 'UI'});
loggerJson.log('Hello Logger.');
// 成果:
// 命名结构函数:{name: UI}
// 默许结构函数:UI
// Hello Logger.

我的本博客原地址:https://ntopic.cn/p/2023102101


扫描二维码推送至手机访问。

版权声明:本文由51Blog发布,如需转载请注明出处。

本文链接:https://www.51blog.vip/?id=267

分享给朋友:

“Flutter/Dart第15天:Dart类结构函数” 的相关文章

RabbitMQ装置

RabbitMQ装置

首要装置Erlang环境 由于 RabbitMQ 需求 erlang 环境的⽀持,所以必须先装置 erlang 。 假如仅仅运用RabbitMQ,个人引荐运用RabbitMQ公司保护的erlang版别,该版别只保留了与RabbltMQ相关的功用, centOS6与7版别的都有,还有erlang19x...

FPGA时序束缚根底

FPGA时序束缚根底

一、时序束缚的意图 因为实践信号在FPGA内部期间传输时,因为触发器等逻辑期间并非抱负期间,因而不可避免地存在传输延时,这种推迟在高速作业频率、高逻辑级数时会形成后级触发器地树立时刻和坚持时刻不满足,形成时序违例。(这也是为什么需求把FPGA规划不能以高档编程言语思想看的原因,规划时,需求做到“心中...

java获取当前时间, Java中的日期时间类

在Java中,你可以使用`java.time`包中的类来获取当前时间。以下是获取当前日期和时间的几种方法:1. 使用`LocalDateTime`类:```javaimport java.time.LocalDateTime;public class CurrentTime { public...

php中文乱码, PHP中文乱码的原因

php中文乱码, PHP中文乱码的原因

1. 设置字符编码: 在PHP文件的开头,使用 `` 来设置输出内容的字符编码为UTF8。 确保你的PHP文件本身也是保存为UTF8编码。2. 数据库连接: 如果你在使用数据库,确保数据库、数据库表和数据库列都使用UTF8编码。 在连接数据库时,设置字符集为UTF8,例如使用...

php开源商城,助力电商企业快速搭建线上平台

1. 萤火商城V2.0 轻量级、高性能、前后端分离的电商系统。 支持微信小程序、H5、公众号、APP。 前后端源码完全开源,支持二次开发。 允许个人学习研究使用,支持二次开发,允许商业用途(仅限自运营)。 2. ShopXO 企业级免费开源商城系统,基于Think...

php代码混淆, 什么是PHP代码混淆?

php代码混淆, 什么是PHP代码混淆?

PHP代码混淆(Obfuscation)是一种将代码转换为难以阅读和理解的形式的技术,目的是保护代码不被未经授权的人轻易理解和篡改。这通常用于保护软件的知识产权,防止他人窃取或逆向工程。1. 变量和函数重命名:将变量和函数的名称替换为无意义的字符或数字,使代码更难以理解。2. 代码合并:将多个文件合...