void main(List<String> args) {
print("Hello Dart");
// 显示声明
String name = 'jack';
// 类型推断:类型推断的,也是有类型的。不同类型之间不能赋值。
// 类型推断变量
var age = 20;
age = 30;
// age = 30.3;
// 编译期常量
const school = '北京大学';
// 运行时常量
final local = DateTime.now();
const p1 = const Person('Tom');
const p2 = const Person('Tom');
const p3 = const Person('LiLei');
print(identical(p1, p2));
print(identical(p1, p3));
}
class Person {
final String name;
// 构造函数传参直接赋值到name属性上。
const Person(this.name);
}
void main(List<String> args) {
// 定义字符串三种方式:单引号,双引号,三引号
var str1 = 'abc';
var str2 = "def";
var str3 = """
ghi
jkl
mn
""";
print(str3);
// 字符串拼接: 拼接规则和shell很相似
var name = 'jack';
var age = 30;
var height = 190.3;
var msg1 = "name is $name, age is ${age}, height is ${height}, height Type is ${height.runtimeType}";
print(msg1);
}
void main(List<String> args) {
// dart中没有关键字定义接口,默认情况下,所有的class都是隐式接口
// dart在集合中广泛使用泛型来表示集合中存放的是什么类型。
// 1.列表List
var names = ['abc', 'cba', 'nba', 'cba', 'abc'];
names.add('hhh');
print(names);
print(names.runtimeType);
// 2.集合Set
var movies = {'星际穿越', '大话西游', '盗梦空间'};
names = Set<String>.from(names).toList();
print(names);
print(movies);
// 3.映射Map
// 映射的Key应该是可以求出hash值的。
var info = {
'name': 'jack',
'age': 30
};
Map;
print(info);
print(info.runtimeType);
}
// 多条语句
testFunc(() {
print('匿名函数被调用');
});
typedef Calculate = int Function(int num1, int num2);
void testFoo2(Calculate cal) {
cal(10, 10);
}
void main(List<String> args) {
print(sayHi(10, 20));
// 顺序可选参数,传参的顺序必须和定义顺序相同
sayHello1('jack', 30);
// 命名可选参数,传参需要带定义的名称
sayHello2('jack', age: 30);
testFunc(foo);
}
// 1.函数的定义
// 返回值类型int 可以省略,但是推荐保留
int sayHi(int height, int age) {
return age + height;
}
// 2.函数的可选参数
/*
dart中没有函数的重载
可选参数:位置可选参数 - 命名可选参数
可选参数可以默认值,必传参数不需要默认值
*/
// 位置可选参数
void sayHello1(String name, [int age, double height]) {
}
// 命名可选参数
void sayHello2(String name, {int age, double height}) {
}
// 命名可选参数带默认值
void sayHello3(String name, {int age, double height = 12}) {
}
// 3.函数是一等公民
/*
一等公民是很灵活的,可以作为参数和返回值。
OC中使用Block实现这一特性
*/
void testFunc(Function foo) {
foo();
}
void foo() {
print('foo 函数被调用');
}
// 4.匿名函数
void testFunc2() {
// 多条语句
testFunc(() {
print('匿名函数被调用');
});
// 单条语句
testFunc(() => print('箭头匿名函数,只能有一条语句') );
// 匿名函数传参
/*
匿名传参,参数需要定义为完整的函数签名:void testFoo(int foo(int num1, int num2)) {}
*/
testFoo((num1, num2) => num1 + num2);
testFoo2((num1, num2) => num1 + num2);
// 匿名返回值
var foo3 = testFoo3();
foo3(3, 3);
}
void testFoo(int foo(int num1, int num2)) {
print(foo(10, 20));
}
typedef Calculate = int Function(int num1, int num2);
void testFoo2(Calculate cal) {
cal(10, 10);
}
Calculate testFoo3() {
return (int num1, int num2) => num1 * num2;
}
5.赋值运算符
void main(List<String> args) {
// ??=: 如果前面的pro为null就执行后面的=赋值操作,如果pro有值就不执行后面的操作。
// 可能有赋值操作
var name = 'jim';
var pro = null;
pro ??= name;
print(pro);
// ??: 是?:三目运算符号的简写, 如果前面的变量有值则取前面的值,如果前面的值为空就取后面的值。
// 一定有赋值操作
var school = '小学';
school = pro ?? '没人上学';
print(school);
// 级联运算符:可以连续调用..方法
var p = Person()
..name = 'jim'
..eat()
..run();
p.eat();
}
class Person {
var name;
void eat() {
}
void run() {
}
}
// 类默认是继承自Object的,应用创建的对象是可以使用Object中的方法的。
class Person {
String name;
int age;
}
Student(this.name, this.age);
c.命名构造函数,因为Dart中不支持函数重载,所以出现了命名构造函数来作为构造函数
Student.withNameAgeHeight(this.name, this.age, this.height);
Student.withMap(Map<String, dynamic> map) {
this.name = map['name'];
this.age = map['age'];
this.height = map['height'];
};
dynamic、var、Object的区别?
// 3.类的初始化列表
class Teacher {
final String name;
final int age;
// Teacher(this.name, {int age = 10, String color}): this.color = color ?? '' {
// }
Teacher():this.name = 'jc', this.age = 10 {
}
}
class Doctor {
int age;
String name;
// 构造函数重定向
Doctor(String name): this._internal(name, 10);
// 命名构造函数
Doctor._internal(String name, int age);
}
// 5.常量构造函数,相同的属性只有一个内存对象。
class Apple {
final String name;
final int age;
const Apple(this.name, this.age);
}
// 6.工厂构造函数:最大的特点可以手动返回一个对象。
class Orange {
String name;
String color;
static final Map<String, Orange> _nameCache = {};
static final Map<String, Orange> _colorCache = {};
factory Orange.withName(String name) {
if (_nameCache.containsKey(name)) {
return _nameCache[name];
} else {
final p = Orange(name, 'red');
_nameCache[name] = p;
return p;
}
}
Orange(this.name, this.color);
}
// 7.Setter, Getter进行属性监听
// 使用方式是: var e = Elephone(); e.setName('jim'); e.getName
class Elephone {
String name;
// 在Dart中没有private public等修饰符,当对属性_开头时,表示这个属性是私有属性,只能在当前文件模块内访问。
String _age;
// setter
set setName(String name) {
this.name = name;
}
// getter
String get getName {
return name;
}
}
// 8.继承:父类的构造函数要在子类的初始化列表中进行调用。
class Animal{
String name;
Animal(this.name);
void eat() {
print('eatting');
}
}
class Dog extends Animal {
int age;
// 父类有构造函数时,需要在参数列表中进行调用,初始化。
Dog(this.age, String name): super(name);
}
// 9.抽象类
abstract class Shape {
int getArea();
String getInfo() {
return '形状';
}
void testMap() {
final m = Map();
print(m.runtimeType);
}
}
class Rectangle extends Shape {
@override
int getArea() {
return 20;
}
}
// 10.dart隐式接口:dart中定义的class同时也可以当接口使用。
class Runner {
void run() {
print('running');
}
}
class Fly {
void fly() {
print('fly');
}
}
class SuperMan extends Animal implements Runner, Fly {
SuperMan(String name):super(name);
// 1.接口实现
@override
void run() {
// TODO: implement run
}
@override
void fly() {
// TODO: implement fly
}
// 2.方法重写
@override
void eat() {
// TODO: implement eat
super.eat();
}
}
// 11.混入mixin
mixin Play {
void play() {
print('play');
}
}
mixin Jump {
void jump() {
print('jump');
}
}
class Robbit extends Animal with Play, Jump {
Robbit(String name):super(name);
@override
void eat() {
// TODO: implement eat
super.eat();
}
}
12.static 类属性,类方法
*/
class SuperWoman {
// 成员变量,成员方法
var name;
void fly() {
}
// 静态/类变量,静态/类方法
static var flyYear;
static void run() {
}
}
void main(List<String> args) {
// 虽然dart支持函数式开发,但是大部分使用的是面向对象开发。
var p0 = Person('jim', 22);
print(p0.toString());
var s0 = Student.withMap({
'name': 'jack',
'age': 18,
'height': 33.3
});
print(s0);
}
// 1.类的基本定义
// 类默认是继承自Object的,应用创建的对象是可以使用Object中的方法的。
class Person {
String name;
int age;
// Person(String name, int age) {
// this.name = name;
// this.age = age;
// }
// 语法糖
Person(this.name, this.age);
}
// 2.类的构造函数
class Student {
String name;
int age;
double height;
// a.普通的构造方法
Student(this.name, this.age);
// b.命名构造函数:因为Dart中不支持函数重载,所以出现了命名构造函数来作为构造函数
Student.withNameAgeHeight(this.name, this.age, this.height);
/*
dynamic和Object的区别
dynamic是类型声明,var是类型推断,它是一个具体类型的声明,如String。
dynamic是运行时报错
Object是编译时报错
Object可以父类指向子类对象。
Object obj = 'hello';
print(obj.toString(1));
*/
Student.withMap(Map<String, dynamic> map) {
this.name = map['name'];
this.age = map['age'];
this.height = map['height'];
}
// c.重新类的描述方法
@override
String toString() {
// TODO: implement toString
return "$age, $name, $height";
}
}
// 3.类的初始化列表
class Teacher {
final String name;
final int age;
/*
构造函数的结构体执行时,是在构造函数执行后,所以对于final属性,它必须在构造函数执行时进行执行
所以此时的执行时间就是在结构体执行时,故:它的执行是在():后面的初始化列表里执行。
初始化列表:里面执行不仅包含编辑期静态返回值,还可以包含动态调用返回值。如:Color.blue
可选命名表达式: 只能有赋值表达式,如:int age = temp ?? 20
*/
// Teacher(this.name, {int age = 10, String color}): this.color = color ?? '' {
// }
Teacher():this.name = 'jc', this.age = 10 {
}
}
// 4.构造函数重定向
class Doctor {
int age;
String name;
// 构造函数重定向
Doctor(String name): this._internal(name, 10);
// 命名构造函数
Doctor._internal(String name, int age);
}
// 5.常量构造函数,相同的属性只有一个内存对象。
class Apple {
final String name;
final int age;
const Apple(this.name, this.age);
}
// 6.工厂构造函数:最大的特点可以手动返回一个对象。
/*
普通构造函数不需要写return 会自动返回实例对象。
工厂构造函数需要写return 手动返回实例对象。
static:全局静态方法,类方法。
*/
class Orange {
String name;
String color;
static final Map<String, Orange> _nameCache = {};
static final Map<String, Orange> _colorCache = {};
factory Orange.withName(String name) {
if (_nameCache.containsKey(name)) {
return _nameCache[name];
} else {
final p = Orange(name, 'red');
_nameCache[name] = p;
return p;
}
}
Orange(this.name, this.color);
}
// 7.Setter, Getter进行属性监听
// 使用方式是: var e = Elephone(); e.setName('jim'); e.getName
class Elephone {
String name;
// 在Dart中没有private public等修饰符,当对属性_开头时,表示这个属性是私有属性,只能在当前文件模块内访问。
String _age;
// setter
set setName(String name) {
this.name = name;
}
// getter
String get getName {
return name;
}
}
// 8.继承:父类的构造函数要在子类的初始化列表中进行调用。
class Animal{
String name;
Animal(this.name);
void eat() {
print('eatting');
}
}
class Dog extends Animal {
int age;
// 父类有构造函数时,需要在参数列表中进行调用,初始化。
Dog(this.age, String name): super(name);
}
// 9.抽象类
// a.子类继承抽象父类,父类的接口方法必须实现,没有option可选项。
// b.抽象类不能实例化
/*
c.系统抽象类Map实例化分析
Map是一个抽象类,而可以调用Map()产生实例对象的原因是因为
调用的Map()是Map抽象类的工厂方法external factory Map();
external 是一个方法存在声明,表示此方法已经存在,但不在这里实现。这样实现和声明分离
的好处是,可以在实现的地方使用runtimeType集中处理不同平台逻辑,而通过方法接口声明在不同的平台
调用。
实现的地方使用@patch修饰。
*/
abstract class Shape {
int getArea();
String getInfo() {
return '形状';
}
void testMap() {
final m = Map();
print(m.runtimeType);
}
}
class Rectangle extends Shape {
@override
int getArea() {
return 20;
}
}
// 10.dart隐式接口:dart中定义的class同时也可以当接口使用。
/*
dart中没有interface/ protocal这样专门定义接口的关键字
dart中定义的class 同时也具有接口的功能,把class当接口使用时,class中定义的方法必须要全部实现。
dart是单继承
*/
class Runner {
void run() {
print('running');
}
}
class Fly {
void fly() {
print('fly');
}
}
class SuperMan extends Animal implements Runner, Fly {
SuperMan(String name):super(name);
// 1.接口实现
@override
void run() {
// TODO: implement run
}
@override
void fly() {
// TODO: implement fly
}
// 2.方法重写
@override
void eat() {
// TODO: implement eat
super.eat();
}
}
// 11.混入mixin
/*
混入mixin间接实现多继承,可以同时引入多个mixin类中的方法
dart是单继承, 如果要想同时引入多个mixin类中的方法,则可以定义多个mixin类来引入
定义用mixin
使用用with
*/
mixin Play {
void play() {
print('play');
}
}
mixin Jump {
void jump() {
print('jump');
}
}
class Robbit extends Animal with Play, Jump {
Robbit(String name):super(name);
@override
void eat() {
// TODO: implement eat
super.eat();
}
}
/*
12.static 类属性,类方法
*/
class SuperWoman {
// 成员变量,成员方法
var name;
void fly() {
}
// 静态/类变量,静态/类方法
static var flyYear;
static void run() {
}
}
7.枚举
void main(List<String> args) {
var color = Colors.red;
switch (color) {
case Colors.blue:
print('蓝色');
break;
case Colors.red:
print('红色');
break;
case Colors.yellow:
print('黄色');
break;
default:
};
print(Colors.values);
}
enum Colors {
red,
blue,
yellow
}
import 'dart:async'; import 'dart:io'; import 'dart:库的名称';
import '08_dart_自定义库_utils/math_utils.dart' 如果自定义库和当前模块或系统库方法名重复,可以是as重命名来区分 import '08_dart_自定义库_utils/math_utils.dart' as MathUtils;
import 'package:http/http.dart' as http;
import '08_dart_自定义库_utils/math_utils.dart' as MathUtils; import '08_dart_自定义库_utils/math_utils.dart' show sum; import '08_dart_自定义库_utils/math_utils.dart' hide sub ;
export 'io_utils.dart'; export 'math_utils.dart';
4.库文件中的私有方法是_开头的方法。
name: zhoufei
description: a dart lib
dependencies:
http: ^0.12.0
import 'dart:math';
import 'dart:convert' as convert;
import '08_dart_自定义库_utils/math_utils.dart' as MathUtils;
// import '08_dart_自定义库_utils/math_utils.dart' show sum;
// import '08_dart_自定义库_utils/math_utils.dart' hide sub ;
import 'package:http/http.dart' as http;
void main(List<String> args) async {
final num1 = 10;
final num2 = 20;
print(min(num1, num2));
MathUtils.sub(num1, num2);
var url =
Uri.https('www.googleapis.com', '/books/v1/volumes', {'q': '{http}'});
// Await the http get response, then decode the json-formatted response.
var response = await http.get(url);
if (response.statusCode == 200) {
var jsonResponse =
convert.jsonDecode(response.body) as Map<String, dynamic>;
var itemCount = jsonResponse['totalItems'];
print('Number of books about http: $itemCount.');
} else {
print('Request failed with status: ${response.statusCode}.');
}
}
/*
dart中,一个文件就是一个模块或一个库
注意:
1.as关键字可以给库起别名
2.默认情况下,导入一个库时会导入库中的所有内容,此时可以使用修饰词声明部分导入
show: 声明要导入的部分
hide: 声明要隐藏的部分
import '08_dart_自定义库_utils/math_utils.dart' as MathUtils;
import '08_dart_自定义库_utils/math_utils.dart' show sum;
import '08_dart_自定义库_utils/math_utils.dart' hide sub ;
3.export统一导出一类库文件,当一个目下有多个工具库时,可以统一放到一个文件中,集中导入防止每个都导入一次
export 'io_utils.dart';
export 'math_utils.dart';
4.库文件中的私有方法是_开头的方法。
5.flutter项目第三方库管理文件pubspec.yaml, 然后执行pub get进行更新。
name: zhoufei
description: a dart lib
dependencies:
http: ^0.12.0
系统库
dart中的Core核心库无需导入,默认导入。如使用的Map
如果使用其他专门功能,就导入专门的库,如:
import 'dart:async';
import 'dart:io';
import 'dart:库的名称';
自定义库
导入方式
import '08_dart_自定义库_utils/math_utils.dart'
如果自定义库和当前模块或系统库方法名重复,可以是as重命名来区分
import '08_dart_自定义库_utils/math_utils.dart' as MathUtils;
第三方库
导入方式
import 'package:http/http.dart' as http;
*/