Dart介绍
- Dart与Flutter的关系就像TypeScript与Angular的关系
- Dart万物皆对象,数字也是,函数也是,null也是,所有对象都继承自Object
- Dart在running走之前解析所有代码,指定类型和编译时常量,能提升代码运行速度
- Dart没有public, protected,private关键字,以下划线(_)定义的变量就是私有变量
Dart关键字
| - | - | - | - |
|---|---|---|---|
| abstract 抽象类 | do | import 导入库 | super 超类 |
| as 类型转换 | dynamic 动态类型 | in | switch 循环 |
| assert 断言 | else | interface 接口(貌似已经移除) | sync* & yield 同步生成器 |
| enum 枚举 | implements 实现接口 | is 类似instanceof | this |
| async* 标识异步生成器函数 | export 导出 | library 定义库的名字 | throw 抛出异常 |
| await 等待 | external 代码的实现由外部提供 | mixin 混入(多继承) | true & false |
| break | extends | new | try & catch |
| case | factory 标识工厂构造函数 | null | typedef 声明函数类型 |
| operator 向量类 | var | class | final |
| part 将库拆分为多个Dart文件 | void | const | finally |
| rethrow 让异常可传播 | while | continue | for |
| return | with 配合mixin | covariant 防止参数缩窄变化报错 | get & set |
| default | if | static | deferred 声明一个延迟加载库 |
Dart内置支持的类型与常用api
- numbers(拥有int, double两个子类,都继承自numbers)
- strings
- booleans
- lists
- maps
- runes(用于在字符串中表示 Unicode 字符)
- symbols
定义常量
- const
const 是在编译时期就必须赋值,而且 const 在类中的话,就必须定义为 static const.(const变量是隐式的final) - final
被final修饰的变量其实不算常量,就是不可变的变量,final只能在类初始化时赋值一次。编译时看不到值
num类型常用API
- isEven 这是表示这个数是不是偶数
void main(){
int x = 18;
print(x.isEven);
}
- isOdd 判断是否是奇数
void main(){
int x = 19;
print(x.isOdd);
}
- toDouble 这是int转double
void main(){
int x = 3;
print(x.toDouble()); //返回结果是3.0
}
- ...各种数学方法(round,floor,ceil,truncate,abs,isInfinite等等)
String 常用API
- 单行与多行字符串
//官网例子
'Single quotes';
"Double quotes";
'Double quotes in "single" quotes';
"Single quotes in 'double' quotes";
// 三个单引号
'''A
multiline
string''';
// 三个双引号
"""
Another
multiline
string""";
- 使用 + 符号连接字符串
'Dart ' + 'is ' + 'fun!'; // 'Dart is fun!'
- 相邻的字符串文字进行串联:
'Dart ' 'is ' 'fun!'; // 'Dart is fun!'
- 字符串插值
String str = 'yuanchen';
String str2 = 'username is ${str}'; //username is yuanchen
- 通过索引符号访问代码单元的字符串表示形式:
String str = 'yuanchen';
print(str[0]) // 'y'
- isEmpty 如果此字符串为空,则返回true。
- isNotEmpty 如果此字符串不为空,则返回true。
- length 返回字符串的长度
- compareTo 粗暴理解为判断当前数字大于等于还是小于指定数字
/*
* 两个数字相等返回0
* 当前数字大于指定数字返回 1
* 当前数字小于指定数字返回 -1
*/
double a = 2.4;
print(a.compareTo(12)) // 1
print(a.compareTo(2.4)) // 0
print(a.compareTo(0)) // -1
- contains 是否包含指定字符串
print('yuanchen'.contains('yuan')); // true
- indexOf 同JavaScript indexOf
print('yuanchen'.indexOf('u')); // 1
- lastIndexOf 字符串最后一次出现的位置
print('www.baidu.com'.lastIndexOf('.')) // 9
- replaceAll 替换所有匹配的子串
const String str = "yuanyuanchen";
print("New String: ${str.replaceAll('yuanyuan','yuan')}"); //yuanchen
- split 字符串转数组
- splitMapJoin 拆分字符串,转换其部分,然后将它们组合为新的字符串
const String str = 'a b,c';
// 查询" , ",用onMatch的返回值替换" , " 用onNonMatch的返回值替换其他
String str1 = str.splitMapJoin(",",
onMatch: (Match match) => "a",
onNonMatch: (String nonMatch) => "b"
);
print(str1) // a b,c -> bab
- toLowerCase 字符串转换为小写
- toUpperCase 字符串转换为大写
- startswith 方法用于检查字符串是否是以指定子字符串开头, 如果参数有 beg 和 end 指定值,则在指定范围内检查。
str = "this is string example....wow!!!";
print str.startswith( 'this' ); // true
print str.startswith( 'is', 2, 4 ); // true
print str.startswith( 'this', 2, 4 ); // false
-
trim去除前后空格 trimLeft & trimRight 同语义
-
noSuchMethod 使用不存在的方法时调用
List 常用API
官网地址: api.dartlang.org/stable/2.5.… 先准备一个List,后面全部操作这个List
const List<Map<String,dynamic>> students = [
{ 'name': 'tom', 'age': 16 },
{ 'name': 'jack', 'age': 18 },
{ 'name': 'lucy', 'age': 20 }
];
List numbers = [2, 8, 5, 1, 7, 3];
- forEach 遍历一个list或者map
students.forEach((student) => print(student));
// {name: tom, age: 16}
// {name: jack, age: 18}
// {name: lucy, age: 20}
Map tom = { 'name': 'tom', 'age': 16 };
tom.forEach((key, value) => print(key + ' - ' + value.toString()));
// name - tom
// age - 16
- map可以用来操作已知数组里的每一项,然后返回一个新数组
var messages = students.map((student) => 'Hello ' + student['name']).toList();
print(messages);
// [Hello tom, Hello jack, Hello lucy]
- contains() 用于判断数组是否包含某个元素
print(numbers.contains(5));
// true
- sort() 用于排序
numbers.sort((num1, num2) => num1 - num2);
print(numbers);
// [1, 2, 3, 5, 7, 8]
- reduce(), fold()
- reduce() 将数组中的每一个值与前面返回的值相加,最后返回相加的总和
- fold() 用法跟 reduce() 基本一样,只不过是可以提供一个初始值
- 还是JavaScript的reduce强大,hahahhaha~
var sum = numbers.reduce((curr, next) => curr + next);
print(sum);
// 26
var sum2 = numbers.fold(10, (curr, next) => curr + next);
print(sum2);
// 36
- every() 用于判断数组中的每一项是否均达到了某个条件
var isAgeOver20 = students.every((student) => student["age"] > 20);
print(isAgeOver20);
// false
var isAgeOver15 = students.every((student) => student["age"] > 15);
print(isAgeOver15);
// true
- where(), firstWhere(), singleWhere()
- where() 返回数组中满足给定条件的元素集合
- firstWhere() 返回数组中满足给定条件的第一个元素
- singleWhere() 返回数组中满足给定条件的唯一一个元素,如果有多个元素满足条件会抛出异常
var ageOver16 = students.where((student) => student["age"] > 16);
print(ageOver16.toList());
// [{name: jack, age: 18}, {name: lucy, age: 20}]
var ageFirstOver16 = students.firstWhere((student) => student["age"] > 16, orElse: () => null);
print(ageFirstOver16);
// {name: jack, age: 18}
var ageUnder20 = students.singleWhere((student) => student["age"] < 16, orElse: () => null);
print(ageUnder20);
// null
- take(), skip()
- take(n) 从数组里取 n 个元素
- skip(n) 跳过数组中的 n 个元素
List arr = [1, 3, 5, 2, 7, 9];
print(arr.take(3).toList());
// [1, 3, 5]
print(arr.skip(4).toList());
// [7, 9]
print(arr.take(3).skip(2).take(1).toList());
// [5]
- List.from() 克隆一个数组
List arr = [1, 3, 5, 2, 7, 9];
var clonedArr = List.from(arr);
print(clonedArr);
// [1, 3, 5, 2, 7, 9]
- expand() 扩大展开列表(类似js中的flat)
var arr1 = [[2, 5], [7], [11, 12]];
var flattened = arr1.expand((item) => item).toList();
print(flattened);
// [2, 5, 7, 11, 12]
var arr2 = [2, 5, 8];
var computed = arr2.expand((item) => [item * 8]).toList();
print(computed);
// [16, 40, 64]
// 当对每一项进行计算时类似于 map()
var computed2 = arr2.map((item) => item * 8).toList();
print(computed2);
// [16, 40, 64]
- add(), addAll()
- add() 向数组中添加一个元素
- addAll() 向数组中添加另一个数组的所有元素
var arr1 = [1, 3, 5, 9, 2, 1];
arr1.add(10);
print(arr1);
// [1, 3, 5, 9, 2, 1, 10]
arr1.addAll([15, 21]);
print(arr1);
// [1, 3, 5, 9, 2, 1, 10, 15, 21]
- clear() 清空数组
numbers.clear(); //[]
Map 常用API
先准备一个map 后面操作它
const Map<dynamic, String>map = {'first': 'dart', 2: 'JavaScript'};
- map赋值
Map<String,dynamic> letterMap = new Map();
letterMap["a"] = "A";
letterMap["b"] = "B";
letterMap["c"] = "C";
print(letterMap); //{a:A, b: B, c: C}
- .isEmpty() 是否是空, .isNotEmpty() 是否非空
print(map.isEmpty()); //false
print(map.isNotEmpty()); //true
- .keys、.values 获取map的键或者值
print(map.keys); //(first,2)
print(map.values); //(dart,JavaScript)
- containsKey()、containsValue() 判断包含某个key、value
print(map.containsKey('first')); //true
print(map.containsValue('PHP')); //false
- remove(),removeWhere() 指定键名删除与根据条件删除
map.remove('first');
print(map); // {2:'JavaScript'}
map.removeWhere((key, value) => key is String);
print(map); // {2:'JavaScript'}
- 遍历map的几种方式
//遍历所有的 key
for (String key in map.keys) {
print('$key');
}
//遍历所有的 value
for (String value in map.values) {
print('$value');
}
//遍历所有的 key-value
map.forEach((key, value) => print('$key == $value'));
- addAll 添加其他键值对到map中
map.addAll({3:"PHP", 4: "JAVA" });
- update(), updateAll() update
- 如果在map中找到了指定的key,就会根据第二个参数指定的规则去修改key对应的value的数据
- 如果没有找到指定的key,就会去查看第三个参数是否设置
- 如果设置了第三个参数,执行完之后会在当前map中添加元素
//存在需要更改的key时
var maps = {'one':'10', 'tow':20,'three': 30};
maps.update('one',(value) {
return '999';
});
print(maps);// {one: 999, tow: 20, three: 30}
//不存在需要更改的key 但是指定了第三个参数
maps.update('four',(value) {
return '999';
},ifAbsent: () => '123');
print(maps);// {one: 10, tow: 20, three: 30, four: 123}
updateAll
var maps = {'one':10, 'tow':20,'three': 30};
maps.updateAll((key, value) {
return value+1;
});
print(maps); //{one: 11, tow: 21, three: 31}
Set常用方法
- set不支持字面量方式常见,只能用过Set构造函数创建,并且不能有重复的值出现
var Set set = new Set();
set.add('a');
set.addAll(['b','c']);
print(set); // {a,b,c}
- difference(), intersection(), union()
- difference 求两个set集合的差集
- intersection 求两个set集合的交集
- union 合并set并去重
//差集
const List<int> list1 = [1,2,3,4];
const List<int> list2 = [2,3];
Set set1 = list1.toSet();
Set set2 = list2.toSet();
print(set1.difference(set2));// {1,4}
//交集
const List<int> list1 = [1,2,3,4];
const List<int> list2 = [2,3];
Set set1 = list1.toSet();
Set set2 = list2.toSet();
print(set1.intersection(set2));// {1,4}
//合并去重
const List<int> list1 = [1,2,3,4];
const List<int> list23 = [2,3,5];
Set set1 = list1.toSet();
Set set2 = list23.toSet();
print(set1.union(set2)); // {1, 2, 3, 4, 5}
- removeAll(), removeWhere() 按值删除和按条件删除
- removeAll 按值删除
- removeWhere 按条件删除
const List<int> list1 = [1,2,3,4];
Set set1 = list1.toSet();
set1.removeAll( { 2, 3 } );
print(set1); //{1, 4}
Set set2 = list1.toSet();
set2.removeWhere((value) => value > 1);
print(set2); //{1}
Dart类 Class
类与对象
1. 什么是Dart中的类
- 使用关键字class声明一个类
- 使用关键字new创建一个对象,new可省略(推荐)
- 所有对象都继承自Object类
void main() {
Persion person = new Persion();
Persion person1 = Persion(); //可以不使用new关键字
}
class Person {
}
2. 类中的属性和方法
- 属性会默认生成getter和setter方法
- 使用final声明的属性只能有getter方法
- 属性和方法只能通过.访问
- 方法不能重载
void main() {
Person person = Person();
person.name = "yuanchen";
person.age = 18;
//访问属性
print(person.name);
//访问方法
person.work();
}
class Person {
String name;
int age;
final String address = ''; //实例只能访问不能更改
void work() {
print("Name is $name, Age is $age, He is Working");
}
}
类和成员的可见性
- Dart中的可见性以library(库)为单位
- 默认情况下。每一个Dart文件就是一个库
- 使用下划线(_)表示私有性
- 使用import导入库
//a.dart
import 'b.dart';
void main() {
Person person = Person();
person.name = "yuanchen";
person.age = 18;
print(person.name);
}
//b.dart
class Person{ //如果Person加上下划线(_) 在a.dart将无法访问到Person类,只在当前文件(b.dart)生效
String name;
int age;
void work() {
print("Name is $name, Age is $age, He is Working");
}
}
计算属性
- 计算属性的值通过计算而来,本身不存储值
- 计算属性赋值,通过计算转换到其他实例变量
- 计算属性就是当前类的属性,而方法主要是为了表达类的某一种行为
void main() {
Rectangle rectangle = Rectangle();
rectangle.width = 20;
rectangle.height = 10;
print(rectangle.area);
//使用setter
rectangle.area = 200;
print(rectangle.width);
}
class Rectangle {
num width, height;
//通过getter返回面积
num get area {
return width * height;
}
//通过setter设置宽度
set area(value) {
width = value / 20;
}
}
构造方法
- 如果没有显式定义构造方法,会有一个默认的构造方法
- 如果存在自定义的构造方法, 默认的构造方法无效
void main() {
Person person = Person('yuanchen', 20);
print('${person.name}-- ${person.age}');
}
class Person {
String name;
int age;
final String gender = '';
//如果不写 Dart会默认创建这样一个构造方法
// Person() {}
Person(String name, int age) {
this.name = name;
this.age = age;
}
void work() {
print("Working");
}
}
- 构造函数语法糖
void main() {
Person person = Person('yuanchen', 20);
print('${person.name}-- ${person.age}');
}
class Person {
String name;
int age;
//构造函数的语法糖
Person(this.name, this.age);
//等价于
// Person(String name, int age) {
// this.name = name;
// this.age = Element.age;
// }
}
- 通过final定义的变量只能通过语法糖或者初始化列表(后面讲)的形式初始化,因为这两种形式初始化属性都是在构造方法执行前初始化的属性
void main() {
Person person = Person('yuanchen', 20,'男');
print('${person.name}-- ${person.age}');
}
class Person {
String name;
int age;
final String gender; //final定义的变量只能通过语法糖或者初始化列表的形式初始化
//构造函数的语法糖
Person(this.name, this.age,this.gender);
}
- 构造方法不能重载,但是有命名构造方法
//使用命名构造方法,可以实现多个构造方法
// 使用类名.方法的形式实现
void main() {
Person person = Person('yuanchen', 20,'男');
print('${person.name}-- ${person.age}');
//实例化命名构造方法
Person person1 = Person.withName('男');
print(person1.gender);
}
class Person {
String name;
int age;
final String gender;
//构造函数的语法糖
Person(this.name, this.age,this.gender);
//命名构造方法
Person.withName(this.gender);
}
- 构造方法可选参数
void main() {
//这里实例化的时候可以不初始化age属性 运行时会使用给定的默认值
Person person = Person('yuanchen');
print('${person.name}-- ${person.age}');
//如果传递了 会覆盖给定的默认值
Person person1 = Person('yuanchen',age: 21);
print('${person1.name}-- ${person1.age}'); //打印出 yuanchen-- 21
}
class Person {
String name;
int age;
//构造函数的语法糖
Person(this.name, {this.age = 20});
}
常量构造方法
- 如果类是不可变状态,可以把对象定义为编译时常量
- 使用const声明构造方法,当前类的所有属性必须都为final
- 使用const声明对象,可以省略
- 使用场景比如属性只会被赋值一次的话,可以使用常量构造方法,因为常量在运行时更快,在编译期就已经确定了
void main() {
const person = const Person('yuanchen', 20);
print(person.name);
}
class Person {
final String name;
final int age;
const Person(this.name, this.age);
}
工厂构造方法
- 构造方法前加factory实现一个工厂方法
- 在工厂构造方法里面可以返回对象
- 使用场景就是flutter中的Json手动序列化
//官网例子 实现缓存效果
class Logger {
final String name;
static final Map<String, Logger> _catch = <String, Logger> {};
factory Logger(String name) {
if(_catch.containsKey(name)){
//工厂构造方法可以返回对象
return _catch[name];
}else {
final logger = Logger._internal(name);
_catch[name] = logger;
//工厂构造方法可以返回对象
return logger;
}
}
Logger._internal(this.name);
void log(String msg) {
print(msg);
}
}
初始化列表
1.初始化列表会在构造方法之前执行
2. 使用逗号分隔初始化列表
3. 初始化列表通常用于设置final变量的值
void main() {
Person person = Person({'name':'yuanchen','age': 20, 'gender':'男'});
print(person.gender);
}
class Person {
String name;
int age;
final String gender;
//初始化列表 也可以对非final属性赋值
Person(Map map): gender = map['gender'], name = map['name']{
this.age = map['age'];
}
}
静态成员
- 使用static关键字声明类级别的属性或者函数
- 静态成员不能访问非静态成员, 非静态成员可以访问静态成员
- 类中的常量需要使用static const类声明
void main() {
Page page = Page();
//静态方法属于当前类,不属于实例,只能通过当前类来调用
Page.scrollDown();
}
class Page {
//类中声明常量要使用static
static const int maxPage = 10;
static int currentPage = 1;
static void scrollDown() {
currentPage = 1;
print('scrollDown....');
}
void scrollUp() {
//scrollUp()方法为非静态成员 所以非静态成员可以访问静态成员
currentPage++;
print('scrollUp....');
}
}
对象操作符
- 级联操作符 (..)
- as 操作符强制更改变量类型
void main() {
Person person = Person();
//级联操作符
person..name = 'yuanchen'
..age = 20;
// as 操作符
var person1;
//这里虽然person1没有被赋值,但是通过as强制转换为了Person类型就可以调用类中的属性或者方法
// 但是当前情况会报错 因为虽然为Person类型 但是它的值为null 使用name属性会报错
(person as Person).name = 'zs';
}
class Person {
String name;
int age;
}
对象call方法
- 如果类实现了call()方法,那么当前类的对象可以作为方法使用(不建议使用)
void main() {
Person person = Person('yuanchen',20);
//直接把对象当作方法来用
person('zs',30);
}
class Person {
String name;
int age;
Person(this.name,this.age);
//实现call方法 名字必须是call
Map call(String name, int age) {
print('Name is $name, Age is $age, He is working');
//有返回值
return {'name':name,'age':age};
}
}
继承
- 使用关键字extends 继承一个类
- 子类会继承父类可见的属性和方法,不会继承构造方法
- 子类能够复写父类的方法,getter setter
- 单继承,多态性
- 所有类默认都继承自Object 因为默认有toString方法
// Person.dart
class Person {
String name;
int age;
String _birthday;
bool get isAdult => age > 18;
void run() {
print('Person is running...');
}
}
//Student.dart
import 'Person.dart';
void main() {
Student student = new Student();
student.study(); //Student study....
student.name = 'yuanchen';
student.age = 16;
//student._birthday = '4.29'; 不能使用父类的私有属性
student.run(); // 重写了父类的方法 打印出Student is running ...
print(student.isAdult); //重写了父类的计算属性 打印出true
//多态性
// 这里将子类的实现赋值给父类的引用 所以这里person这个实例只能调用person的方法和属性
Person person = new Student();
person.age = 16;
print(person.isAdult);// true 因为这里虽然是父类的类型 但是用的是子类的实现 所以返回true
}
//通过extends 继承Person
class Student extends Person{
void study() {
print('Student study....');
}
//重写父类的计算属性
bool get isAdult => age > 15;
//重写父类的方法
void run() {
print('Student is running ... ');
}
}
继承中的构造方法
- 子类的构造方法默认会调用父类无名无参的构造方法
void main() {
Student student = Student(); //会打印出 Person...
}
class Person {
String name;
Person() {
print('Person....');
}
}
class Student extends Person {
int age;
}
- 如果父类没有无名无参的构造方法,需要显式调用父类构造方法
- 在构造方法参数后使用冒号(:) 显示调用父类构造方法
void main() {
Student student = Student('yuanchen');
print(student.name);
}
class Person {
String name;
Person(this.name);
Person.withName(this.name);
}
class Student extends Person {
int age;
//如果父类中没有无名无参的构造方法 就需要显示的调用构造方法
Student(String name) : super(name);
//如果父类中有命名构造方法 也可以显式调用父类命名构造方法
//Student(String name): super.withName(name);
}
- 父类的构造方法在子类构造方法体开始执行之前调用
- 如果有初始化列表,初始化列表会在父类构造方法之前执行
void main() {
Student student = Student('yuanchen','男');
print(student.name);
}
class Person {
String name;
Person(this.name);
Person.withName(this.name);
}
class Student extends Person {
int age;
final String gender;
//初始化列表的gender会在父类的super之前调用
Student(String name, String gender) : gender = gender ,super(name);
}
抽象类
- 抽象类使用abstract表示,不能直接实例化
- 抽象类可以没有抽象方法
abstract class Person {
//抽象类可以没有抽象方法
//有一个空实现 没有抽象方法
void run(){}
}
- 抽象方法不需要abstract修饰,无实现
abstract class Person {
void run();
}
- 有抽象方法的类一定要声明成抽象类
- 实现抽象类
void main() {
Person person = new Student(); //多态
person.run();
}
abstract class Person {
void run();
}
class Student extends Person {
void run() {
print('继承抽象类 实现抽象方法');
}
}
- dart中的抽象类更像其他语言中的接口
接口
- 类和接口是统一的, 类就是接口(这点很奇怪)
- 每个类都隐式的定义了一个包含所有实例成员的接口
- 如果是复用已有的类的实现,使用继承(extends)
- 如果是使用已有的类的行为,使用接口(implements进行实现接口)
void main() {
Student student = new Student();
print(student.age); //10
}
class Person {
String name;
int get age => 18;
void run() {
print('person run ...');
}
}
class Student implements Person{
@override
String name;
@override
// TODO: implement age
int get age => 10;
@override
void run() {
// TODO: implement run
}
}
- 最好是使用抽象类作为接口,这样更像是一个接口,上面那种形式(类就是接口)很奇怪
void main() {
Student student = new Student();
student.run(); //10
}
abstract class Person {
void run();
}
class Student implements Person{
@override
void run() {
print('Student is running ....');
}
}
Mixins
- Mixins使用with连接一个或者多个minxin,似于多继承,是在多继承中重用一个类代码的方式
void main() {
D d = new D();
d.a(); //A.a()....
d.b(); // B.b()....
d.c(); // C.c()....
}
class A {
void a() {
print("A.a()....");
}
}
class B {
void b() {
print("B.b()....");
}
}
class C {
void c() {
print("C.c()....");
}
}
//同时继承ABC三个类
class D extends A with B, C{
}
- 作为Mixin的类不能有显式声明的构造方法
void main() {
D d = new D();
d.a(); //A.a()....
d.b(); // B.b()....
}
class A {
void a() {
print("A.a()....");
}
}
class B {
//作为Mixin 不能有显示的构造方法
// B() {}
void b() {
print("B.b()....");
}
}
//同时继承ABC三个类
class D extends A with B{
}
- 作为Mixin的类只能继承自Object 不能有其他继承
4.Mixin 既能实现多继承也能实现组装 将多个不同功能的类 组装成一个最终类
abstract class Engine {
void work();
}
class OilEngine implements Engine {
@override
void work() {
print('Work with oil');
}
}
class ElectricEngine implements Engine {
@override
void work() {
print('Work with Electric');
}
}
class Tyre {
String name;
void run() {}
}
//使用电的汽车
class Car = Tyre with ElectricEngine;
//使用油的汽车
class Bus = Tyre with OilEngine;
//上面两种方式其实的实现如下
//这种其实就是多继承 然后再继承的基础上再实现当前类的行为 两种不同的用法
class Car1 extends Tyre with ElectricEngine {
String color;
}
- 我感觉这个东西强的一批, 可以把不同的业务模块拼到一起
操作符覆写
- 覆写操作符需要再类中定义
//覆写操作符的格式
//返回值 operator 要覆写的符号 (参数列表) {
//方法体
//}
void main() {
Person person1 = Person(18);
Person person2 = Person(20);
//对象是没有大于符号(>)的 但是可以通过重写大于符号来实现对象之间的比较
print(person1 > person2); //false
//对象访问属性或者方法是使用点(.)的形式访问,如果想通过['age']的形式访问 可以通过重写操作符的形式实现
print(person1['age']);
}
class Person {
int age;
Person(this.age);
bool operator >(Person person) {
return this.age > person.age;
}
int operator [](String str) {
if ("age" == str) {
return age;
}
return 0;
}
}