自学Dart

Dart是强类型语言支持指定类型(内置类型和自定义类型),也支持动态类型推导。
Dart中所有变量都是对象类型(所有类型都是Object的子类,包括Function和Null),Dart初始值为null。
Dart定义变量和数据类型(泛型):
支持指定类型(内置类型和自定义类型),变量初始化为一种数据类型,不能将其他数据类型赋值给该变量(dynamic除外),支持类型推导。
类型推导变量
var 关键字声明变量,编译时确定类型(初始化类型后不能更改,不推荐使用)。

var a = 1;

(指定内置类型变量)
dynamic 关键字声明变量并指定运行时类型(赋值后可以更改类型)。

dynamic a1 = 1;
  a1 = true;
  a1 = '123';

String 关键字声明变量并指定编译时类型(字符串类型)

String a2 = '1';

num 关键字声明变量并指定编译时类型(数字类型,不推荐 )

num a3 = 1;

int 关键字声明变量并指定编译时类型(整数类型)

int a4 = 1;

double 关键字声明变量并指定编译时类型(浮点数类型)

double a5 = 1.0;

bool 关键字声明变量并指定编译时类型(布尔类型)

bool a6 = true;

List 关键字声明变量并指定编译时类型(列表类型)

List a7 = [1, '2', true]; // 列表(数组)
List a8 = <String>['1', '2']; // 泛型列表(数组)
List a9 = List.filled(2, ''); // 固定长度列表(数组)
List a10 = List<int>.filled(2, 1); // 泛型固定长度列表(数组)

Map 关键字声明变量并指定编译时类型(映射类型)

Map a11 = {'name': '张三', 'age': 20}; // Maps映射

Set 关键字声明变量并指定编译时类型(集合类型)

Set a12 = {}; // Set集合

Function 关键字声明变量并指定编译时类型(函数类型)

Function a13 = ((){
   return(){};
 })();

自定义关键字声明变量并指定编译时类型一般在类中运用较多(自定义类型)。

Dart定义常量:类型推导常量和指定类型常量
final 声明常量,运行时确定常量(只初始化类型一次)。
const 声明常量,编译时确定常量。

final b1 = DateTime.now();

const 声明常量,编译时确定常量。

/* 常量构造函数 */
class Fish {
  /* 成员变量都是final修饰 */
  final int a;
  void b() {}
  /* 构造函数用const修饰 */
  const Fish(this.a);
  const Fish.play(this.a);
  Fish b6 = const Fish(1); // 实例化常量构造函数
  const b7 = Fish(1);// 和上面一样,另一种写法
}
const b2 = 1;
Set b3 = const {}; // 声明常量集合
Map b4 = const {}; // 声明常量映射
List b5 = const [1, 2, 3]; // 声明常量列表

final 类型关键字 声明常量并指定运行时常量类型。

final DateTime b7 = DateTime.now();
String b8 = 'aaa';
final int b9 = b3.length;

const 类型关键字 声明常量并指定编译时常量类型。

const int b10 = 1;

操作符

String? c; // 可为空操作符
  print(c?.length); // 可选操作符
  print(c!.length); // 类型断言操作符
  
List c1 = [1, 2, 3];
  dynamic c2;
  List c3 = [...c1, 4, 5, 6]; // [1, 2, 3, 4, 5, 6] 扩展运算符
  List c4 = [1, 2, 3, ...?c2]; // [1, 2, 3] 空感知运算符

class C {
  String name = '小红';
  int age = 18;
  String sex = '女';
}
C c5 = C();
c5..name = '张三'..age = 20..sex = '男'; // 级联操作符

dynamic c6;
  c6 ??= 12; // b6没有被赋值,则b6被赋值12,b6有值,不做操作。
  int c7 = c6 ?? 10; // b6没有值,则10赋值给b7,b6有值,则b6赋值给b7。

Dart类型转换:
toString() 其他类型(一般是Number类型)转String类型
parse() 其他类型(一般是String类型)转Number类型
toList() 其他类型转List类型
join(‘’) 数组转字符串(返回值String类型)
split(‘’) 字符串转数组(返回值List类型)
as 类型转换(类型推导错误,手动指定类型)

 int d1 = 1;
 String d2 = '1';
 List d3 = [1, 2, 3];
 print(d1.toString() == '1'); // true
 print(int.parse(d2) == 1); // true
 print(d3.reversed); // (3, 2, 1)
 print(d3.reversed.toList()); // [3, 2, 1]
 print(d3.join('-')); // 1-2-3
 print(d2.split('')); // [1]

Dart类型判断:
isEmpty 判断是否为空
isNotEmpty 判断是否不为空
isNaN 判断是不是NaN
isOdd 判断是不是奇数
isEven 判断是不是偶数
is 关键词判断类型
if判断
switch case判断

  List e1 = [];
  int e2 = 12;
  print(e2.isNaN); // false
  print(e2.isEven); // true
  print(e2.isOdd); // false
  print(e1.isEmpty); // true
  print(e1.isNotEmpty); // false
  print(e2 is String); // false
  bool e3 = true;
  List e4 = [1, 2, 3, if (e3) 4]; // [1, 2, 3, 4]
  e3 = false;
  List e5 = [1, 2, 3, if (e3) 5]; // [1, 2, 3]

Dart循环语句:
for循环
forEach循环(void返回值类型)
for in 循环
map循环(返回值新数组)
while循环
do while循环

  List f1 = [1, 2, 3, 4, 5];
  List f2 = [1, for (dynamic i in f1) i + 1]; // [1, 2, 3, 4, 5, 6]
  /* 
  原理
  for (dynamic i in f1) {
    f2.add(i + 1);
  }
  */

导入库需要部分

import '' show ;

隐藏库不需要部分

import '' hide ;

as 库重命名

import '' as http;

懒加载库

import '' deferred as http;

List有序的列表
List常用属性和方法:
length 列表长度
reversed 列表翻转
add(el) 列表末尾添加(void返回值类型)
addAll([el]) 拼接数组(void返回值类型)
indexOf(el,index = 0) 返回查找的元素索引或者-1
remove(el) 根据具体值删除(返回值true或者false)
removeAt(index) 根据索引删除(返回值删除的元素)
fillRange(index,indexend,el) 根据索引修改元素(void返回值类型)
insert(index,el) 指定位置插入(void返回值类型)
insertAll(index,List) 指定位置拼接列表(void返回值类型)

  List g1 = [
    1,
    '1',
    true,
    {'c': 1},
    [1]
  ];
  print(g1.length);
  print(g1.reversed); // ([1], {c: 1}, true, 1, 1)
  g1.add(2);
  g1.addAll([3]);
  g1.addAll({3});
  g1.indexOf(1, 0);
  g1.remove([1]);
  g1.removeAt(c1.length - 1);
  g1.fillRange(0, 1, [124]);
  g1.insert(0, [0]);
  g1.insertAll(0, [123456]);

Set没有顺序不能重复的集合
常见属性和方法:
length 集合长度
first 返回集合首个元素
last 返回集合末尾元素
add(el) 集合末尾添加(void返回值类型)
addAll({el}) 拼接集合(void返回值类型)
remove(el) 根据具体值删除(返回值true或者false)
clear() 清除集合
contains 查找元素(返回值布尔类型)
containsAll 查找集合(返回值布尔类型)

Set h2 = {};
h2.add('name'); // {name}
h2.addAll([1, 2, 3]); // {name, 1, 2, 3}
h2.addAll({1, 2, 3}); // {name, 1, 2, 3}
print(h2.first); // name
print(h2.last); // 3
print(h2.remove('name')); // true
print(h2.contains(1)); // true
print(h2.containsAll({1, 2, 3})); // true
print(h2.containsAll([1, 2, 3])); // true
h2.clear(); // {}

Maps无序的键值对,键不可重复,值可以多次重复
常见属性和方法:
length 映射长度
keys 获取所有key
values 获取所有value
containsKey(key) 查找key(返回值布尔类型)
containsValue(value) 查找value(返回值布尔类型)
putIfAbsent(key,fn) 根据key,查找value并返回,没找到,则插入给定的key,value并返回插入的value
remove(key) 根据key删除key,value(返回删除的value)
clear() 清空映射
update(key,fn,ifAbsent) 根据key更新value并返回value,找不到key,调用ifAbsent函数,添加key,value并返回value
updateAll(fn) 遍历所有key并更新value
addAll() 拼接映射(void返回值类型)

Map i3 = {};
  i3['name'] = '张三'; // 添加键值对
  i3['age'] = 18; // 添加键值对
  print(i3.containsKey('name')); // true
  print(i3.containsValue('张三')); // true
  print(i3.putIfAbsent('name', () => {'name': '李四'})); // 张三 {name: 张三, age: 18}
  print(i3.putIfAbsent('lis',() => {'name': '李四'})); // {name: 李四}, {name: 张三, age: 18, lis: {name: 李四}}
  print(i3.remove('age')); // 18
  i3.update('sex', (val) => val = '男',ifAbsent: () => '女'); // 女, {name: 张三, age: 18, sex: 女}
  print(i3.update('age', (value) => value = 20)); // 20
  i3.updateAll((key, val) => {key = 1, key = 2, key = 3}); // {name: {1, 2, 3}, age: {1, 2, 3}}
  i3.clear(); // {}

where(fn):过滤符合条件的元素(返回值是符合条件的元素)
any(fn):有符合条件的元素(返回值是布尔值)
every(fn):全部符合条件的元素(返回值是布尔值)
reduce(fn):把元素两两挑出来,执行函数。(返回值是操作的结果)
函数返回值类型 函数名(形参){…return} 函数名(实参)

/* 必选参数 */
int j1(int age,String name,) {
    print(name);
    return age;
  }
  j1(18, '张三');
  
  /* 可选参数[age 有初始化值(可传可不传),className 允许为null值(可传可不传)] */
  void j2(String name, [int age = 12, String? className]) {
    print(name); // 李四
    print(age); // 12
    print(className); // null
  }
  j2('李四');

/* 命名参数{age 允许为null值(可传可不传),className 不允许为null值(必须传值),sex 有初始花值(可传可不传)} */
  void j3(String name, {int? age, required String className, String sex = '男'}) {
    print(name); // 王五
    print(age); // null
    print(className); // 大四
    print(sex); // 男
  }
  j3('王五', className: '大四');
  
/* 高阶函数 */
  void j4(fn) {
    fn();
  }
  j4(j3);
  
  /* 带参数高阶函数 */
  void j5(void Function(String a, {int? b, double? c}) foo) {}
  typedef Calculate = int Function(String a, {int b, double c}); // 函数签名(推荐写法)
  void j5(Calculate calc) {calc('a');}
 j5((a, {b = 1, c}) {});
 
/* 立即执行函数(自执行函数) */
  (() {})(); // 推荐这种写法
  (() {}());
  
/* 匿名函数,闭包,箭头函数(只能执行一条语句) */
  Function j6() {
    return () {
      return () => print('箭头函数');
    };
  }

  Function j7 = j6();

类(封装,继承,多态),抽象类,常量类,普通类

abstract 关键字定义抽象类,没有方法体的方法是抽象方法,抽象类不能实例化默认构造函数,可以实例化工厂构造函数,抽象类可以当接口,也可以当父类,Dart中接口很奇怪,所有类都可以当接口,implements 关键字实现接口,推荐使用抽象类当接口。
extends: 继承
子类继承父类普通的成员(属性和方法),不继承构造函数(默认和命名)
父类默认构造函数(有参数)需要 super 关键字传参数命名构造函数需要 super 调用,子类可以重写父类方法(方法形参类型和个数必须一样,方法返回值类型可以不同)
父类是抽象类子类是普通类必须实现父类所有抽象方法
多态:
允许将子类类型的指针赋值给父类类型的指针。
子类的实例赋值给父类的引用(Animal e = Dog()😉
父类定义一个方法,不去实现,让他的子类去实现(子类实现父类抽象方法)。

// class.dart文件

abstract class Person {
/* static 关键字实现静态成员(属性和方法),静态方法不能访问非静态成员,非静态方法可以访问静态成员,只能通过类自身访问 */
  static late String name;
  static int? age;
  static String sex = '男';
  static void run() {}

/* 抽象方法 */
  eat();

/* 普通成员 */
  late String hobby; // 延迟初始化
  String? occupation; // 可以为空
  String career = '计算机'; // 初始化值
  void speak(int a, String b) {}

  /* 私有成员 */
  late int _a;
  bool? _b;
  final String _c = '私有属性';
  void _d() {}

  /* 默认构造函数(简写)  : this.cry(occupation, a)函数重定向  */
  Person(String occupation, String a) : this.cry(occupation, a);

  /* 工厂构造函数 */
  factory Person.foo() {
    return Person
        .foo(); // 因为是抽象类,所以只能这么写-_-!懒得写子类,抽象类可以实例化工厂构造函数(看dart源码),不能实例化普通构造函数。
  }

  /* 命名构造函数和默认构造函数不同,实例化不会自动执行。this.hobby = hobby :occupation = '程序员' 调用cry构造函数时默认初始化 */
  Person.cry(this.occupation, String a) : hobby = '飞盘' {
    speak(1, '1');
  }

  /* 命名构造函数 可选参数 */
  Person.smile(this.occupation, String a, [String? b, String c = '1'])
      : hobby = b ?? '足球'; /* 可选参数c */

  /* 命名构造函数 命名参数 */
  Person.play(
    this.occupation,
    String a, {
    required String b,
    /* required 必须传值 */
    String c = '1',
  });

/* get修饰符(不能接受参数) */
  get secret {
    return '$_a $_b $_c';
  }

/* set修饰符(只能有一个参数) */
  set amend(val) {
    _a = val;
    _d();
  }
}

// main.dart

/* 普通类继承抽象类,必须实现抽象类方法 */
class Man extends Person {
/* Man(String name) : super(name); */
  Man(super.name); // 两种写法

   // 注解 实现抽象类方法
  eat() {
    throw UnimplementedError();
  }

   // 注解 按需重写父类方法(形参类型和数量必须一样,方法返回值类型可以不同)
  String speak(int a, String b) {
    super.speak(a, b); // 调用父类方法
    return 'a';
  }
}

/* 抽象类继承抽象类,不用实现父类抽象方法 */
abstract class Woman extends Person {
  Woman(super.occupation);
}

implements:
实现接口,必须实现接口和接口继承的父类的所有普通成员,get修饰符,set修饰符,抽象方法

/* 实现接口,必须实现接口和接口继承的父类的所有普通成员,get修饰符,set修饰符,抽象方法 */
class Child implements Man, Woman {
  
  late String career;

  
  late String hobby;

  
  String? occupation;

  
  set amend(val) {}

  
  eat() {}

  
  get secret {}

  
  String speak(int a, String b) {
    return '实现接口';
  }
}

mixin混入


 void main() {
  A a = A();
  a.eat();
  a.run();
}

mixin Animal {
  void run() {}
}

mixin Flsh {
  void eat() {}
}

class A with Animal, Flsh {}

枚举

void main() {
  print(Animal.values);
}

enum Animal { eat, run, speak }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值