当前位置: 首页 > news >正文

Dart语言之面向对象

目录

前言

1、初始化列表和标准构造方法

2、命名构造方法

3、工厂构造方法

4、命名工厂构造方法

5、set&get&静态方法

6、抽象类

7、mixins

8、方法

9、泛型


前言

本篇继续来学习Dart语言的内容,今天接上一篇《Dart语言之常用数据类型》来介绍Dart里面的面向对象。面向对象的核心特性包括封装、继承和多态

1、初始化列表和标准构造方法

类是面向对象编程的核心概念,包含对象、变量和方法。在Dart中定义类时,所有类默认继承自Object。

定义类变量的语法为:在类的大括号内直接声明变量类型和变量名,构造方法用于初始化类的对象。多态的表现形式包括方法重载,例如重写父类的toString方法,举个栗子如下:

/// 定义一个类,所有的类都继承自Object
class Person {String name;int age;/// 标准的构造方法Person(this.name, this.age);/// 重写父类方法@overrideString toString() {return '$name,$age';}
}

初始化列表位于构造方法冒号后的表达式,用于初始化类的变量。

私有变量通过下划线标识,仅在当前文件内可访问:String _school;

可选参数通过大括号声明:Student({String city});

默认参数在可选参数后通过等号设置默认值,例如:Student({String country = 'China'});

可选参数和默认参数不仅适用于构造方法,也适用于其他类型的方法。

初始化列表可在子类构造方法体之前设置,用于初始化实例变量。若父类没有无参构造方法,则需在初始化列表中调用父类的构造方法。构造方法的方法体可通过大括号设置,但非必须。示例:

class Student extends Person {// 定义类的变量String? _school; // 私有变量通过下划线标识,仅在当前文件内可访问String? city;String? country;late String name;/// 构造方法:/// 通过this._school初始化自有参数/// name,age交给父类进行初始化/// city为可选参数/// country为默认参数Student(this._school,String name,int age, {this.city,this.country = '中国',}) : // 初始化列表可在子类构造方法体之前设置,用于初始化实例变量。例如:name = '$country-$city',// 若父类没有无参构造方法,则需要在初始化列表中调用父类的构造方法super(name, age) {// 构造方法体不是必须的print('构造方法的方法体不是必须的');}
}

2、命名构造方法

命名构造方法是开发过程中常见的一种构造方法形式。命名构造方法以类名开头,通过点符号连接自定义方法名,用于实现类的多构造方法功能。

// 命名构造方法【类名+.+方法名】
Student.convert(Student stu) : super(stu.name, stu.age);

3、工厂构造方法

在 Dart 中,使用 factory 关键字在构造方法前定义一个工厂构造方法。它允许你在构造函数中执行自定义逻辑,比如返回一个已存在的实例(实现单例模式)、返回子类实例,或者根据条件返回不同类型的实例。与普通构造函数不同,工厂构造方法需要显式使用 return 关键字来返回一个对象,并且不一定要返回新的实例。 

定义工厂构造方法:

  • 使用 factory 关键字:在类定义中,在构造方法的声明前加上 factory 关键字。
  • 实现逻辑:在方法体内部编写创建和返回对象的逻辑。
  • 使用 return 关键字:工厂构造方法必须使用 return 关键字返回一个对象。
class Singleton {static Singleton? _instance; // 静态变量,缓存实例// 私有命名构造函数Singleton._internal();// 工厂构造方法factory Singleton() {if (_instance == null) {// 如果实例不存在,就创建一个新的实例_instance = Singleton._internal();}// 返回缓存的实例return _instance!;}
}void main(){var s1 = Singleton();var s2 = Singleton();print(s1 == s2); // 输出:true
}

4、命名工厂构造方法

命名工厂构造方法的主要形式如下:

  • 通过factory关键字标识
  • 类名加点加自定义方法名构成
  • 参数可根据需要设置
  • 可返回构造方法并根据需要进行初始化
  • 无需将类final变量作为参数,是一种灵活的获取类对象的方式
// 命名工厂构造方法:factory [类名+.+方法名]// 它可以有返回值,而且不需要将类的final变量作为参数,是一种灵活获取类对象的方式factory Student.stu(Student stu){return Student(stu._school, stu.name, stu.age);}

5、set&get&静态方法

set方法用于修改私有字段值,需使用set关键字声明:

// 可以为私有字段设置setter来控制外界对私有字段的修改set school(String value) {_school = value;}

get方法用于为私有字段设置访问接口,允许外部代码获取私有字段值:

// 可以为私有字段设置getter来让外界获取到私有字段String? get school => _school;

静态方法使用static关键字标识,属于类而非实例,调用方式为类名.方法名(),无需创建类实例:

// 静态方法static doXXX(String str) {print('doXXX:$str');}

6、抽象类

抽象类的定义需使用abstract关键字修饰。例如,定义Study抽象类时需标注为abstract class Study。抽象类的作用主要体现在接口定义场景。

/// 使用abstract来定义抽象类,该类不能被实例化,在定义接口时非常有用
abstract class Study{void study(); // 抽象方法@overrideString toString() {return '抽象类中的普通方法';}
}
/// 继承抽象类要实现它的抽象方法,否则也需要将自身定义成抽象类
class StudySon extends Study{@overridevoid study() {// TODO: implement study}
}

7、mixins

mixin的特征包括:

  • 必须创建继承自object的子类
  • 不能继承其他类
  • 不能声明构造方法
  • 不能调用super
mixin class OldMan{void workOld(){print('OldMan');}
}
mixin class YoungMan{void workYoung(){print('YoungMan');}
}
class Worker with OldMan,YoungMan{@overridevoid workOld() {// TODO: implement workOldsuper.workOld();}@overridevoid workYoung() {// TODO: implement workYoungsuper.workYoung();}
}class Worker extends OldMan with YoungMan{@overridevoid workOld() {// TODO: implement workOldsuper.workOld();}@overridevoid workYoung() {// TODO: implement workYoungsuper.workYoung();}
}

8、方法

①、方法的完整结构包含以下要素:

  • 返回值:定义方法执行后的输出类型,可为void或具体数据类型
  • 参数:接收外部输入的变量集合
  • 方法名:方法的唯一标识符(匿名方法除外)

其中,返回值特性包括:

  • 类型可缺省,默认返回void类型
  • 需显式声明返回具体数据类型时,必须包含return语句
  • 匿名方法作为特例可不声明方法名

以及,方法参数具有以下特征:

  • 参数类型与参数名共同构成参数声明
  • 参数分类:
    • 可选参数
    • 默认参数
  • 构造方法的参数规则完全适用于普通方法

②、私有方法的核心特征:

  • 命名规范:以下划线开头
  • 作用域限制:仅在定义文件中可访问

应用范围:同样适用于私有字段和私有类

③、匿名方法的定义:

  • 无方法名的即时函数定义

常见应用场景:作为回调函数参数

class FunctionLearn {int sum(int value1, int value2) {return value1 + value2;}_learn() {print('私有方法');}anonymousFunction() {const list = ['func1', 'func2'];list.forEach((item) {print('item: $item');});}
}

关于其它类型的方法在上面基本上都已经介绍了,这里不再赘述。

9、泛型

最后来看一下泛型的使用,泛型的核心价值在于提升代码复用性,支持对非特定数据类型的通用操作。在 Dart 中,通过在类名后添加一对尖括号 <T> 来定义泛型类,其中 T 是一个泛型占位符,表示一个不确定的类型。如果需要多个泛型参数,可以使用逗号分隔,例如 <T, E>。泛型类可以在实例化时指定具体的类型,以提高代码的复用性和类型安全。 

示例代码如下:

class Cache<T> {final Map<String, T> _cached = <String, T>{};void setItem(String key, T value) {_cached[key] = value;}T? getItem(String key) {return _cached[key];}
}void main() {var ca = Cache<String>();ca.setItem('key', '123');print(ca.getItem('key'));
}

关键点:

  • 定义泛型类:在类名后面使用尖括号 <T> 来声明泛型参数。
  • 使用泛型参数:在类的方法、属性等中使用泛型参数 T 来表示一个不确定的类型。
  • 实例化:在创建类的实例时,通过 <具体类型> 指定泛型参数的类型,例如 Cache<int>()
  • 多个泛型参数:可以使用逗号分隔多个泛型参数,例如 class MyMap<K, V>
  • 类型约束:可以使用 extends 关键字来限定泛型参数的类型,例如 class NumericCache<T extends num> 表示 T 必须是 num 或其子类。 

OK,到这里今天的内容就介绍完了,更多详情请参考文档:https://dart.dev/docs

下期再会,祝:工作顺利!

http://www.dtcms.com/a/610183.html

相关文章:

  • Ubuntu 22.04双网口同时使用 MID360 雷达与上网的完整指南
  • 广东兰州企业网站排名优化
  • oh my zsh配置
  • 光电对抗——有源干扰:从原理到外场实验(续)
  • nn实践-使用nn搭建一个定时发送天气预报邮件的工作流
  • 网站优化公司方案门户导航网页模板
  • 加强网站建设 提升做网站前台需要什么技能
  • GMI Cloud@AI周报 | Kimi K2-Thinking突袭赶超;OpenAI发布GPT-5.1;豆包编程模型发布
  • 电流检测放大器IC 汽车前装无线充电模块应用 FP130A
  • 扣子——插件问题完整排查报告
  • 网站建设用户登录想招代理去什么网站
  • 广东省备案网站建设方案书外贸做的亚马逊网站是哪个
  • Linux互联网基础
  • 房建设计图网站网站建设目的主要包括哪些
  • 深入理解 Spring Boot 单元测试:从基础到最佳实践
  • react 封装弹框组件 传递数据
  • 宿州做网站安卓系统app
  • 用Maven的quickstart archetype创建项目并结合JUnit5单元测试
  • ELK Stack核心原理与运用要点解析
  • Spring前置准备(九)——Spring中的Bean类加载器
  • TDengine 字符串函数 LTRIM 用户手册
  • 【十一、Linux管理网络安全】
  • 免费的行情软件网站下载不用下载二字顺口名字公司
  • YOLOv5/8/9/10/11/12/13+oc-sort算法实现多目标跟踪
  • Android开发从零开始 - 第一章:Android概述与工程项目结构
  • Spring Boot 应用启动报错:FeignClientSpecification Bean 名称冲突解决方案
  • 个人网站建立平台俄罗斯军事基地
  • h5 建站网站 移动端大数据在营销中的应用
  • 基于RetinaNet的建筑设计师风格识别与分类研究_1
  • Mysql假如单表数据量上亿,会出现什么问题