继承
实现继承
class Phone {
void startup() {
print('开机');
}
void shutdown() {
print('关机');
}
}
class AndroidPhone extends Phone {
}
void main() {
var p = AndroidPhone();
p.startup();
p.shutdown();
}
开机
关机
父类调用
class Phone {
void startup() {
print('开机');
}
void shutdown() {
print('关机');
}
}
class AndroidPhone extends Phone {
@override
void startup() {
super.startup();
print('AndroidPhone 开机');
}
}
void main() {
var p = AndroidPhone();
p.startup();
}
开机
AndroidPhone 开机
super 对象可以访问父类
调用父类构造
class Mobile {
int number;
Mobile(this.number);
void showNumber() {
print('010-$number');
}
}
class AndroidPhone extends Mobile {
AndroidPhone(int number) : super(number);
}
void main() {
var p = AndroidPhone(12345678);
p.showNumber();
}
010-12345678
可调用父类的 构造函数
重写超类函数
class Mobile {
int number;
Mobile(this.number);
}
class AndroidPhone extends Mobile {
AndroidPhone(int number) : super(number);
@override
void noSuchMethod(Invocation mirror) {
print('被重写 noSuchMethod');
}
}
void main() {
dynamic p = AndroidPhone(12345678);
p.showNumber111();
}
被重写 noSuchMethod
在重写的函数上加修饰符
@override
继承抽象类的问题
abstract class IPhone {
void startup() {
print('开机');
}
void shutdown();
}
class AndroidPhone extends IPhone {
@override
void startup() {
super.startup();
print('AndroidPhone 开机');
}
@override
void shutdown() {
print('AndroidPhone 关机');
}
}
void main() {
var p = AndroidPhone();
p.startup();
p.shutdown();
}
开机
AndroidPhone 开机
AndroidPhone 关机
抽象类中只定义抽象函数,实例化访问会报错
多继承
多继承 with
- 定义类
class Phone {
void call() {
print('Phone is calling...');
}
}
class Android {
void playStore() {
print('Google play store');
}
}
class Ios {
void appleStore() {
print('Apply store');
}
}
- with 混入
class Xiaomi with Phone, Android, Ios {}
采用
with ... , .... , ...方式 mixin 入多个类功能
- 执行
void main(List<String> args) {
var p = Xiaomi();
p.call();
p.playStore();
p.appleStore();
}
Phone is calling...
Google play store
Apply store
函数重名冲突
- Android Ios 加入 call 函数
class Android {
void playStore() {
print('Google play store');
}
void call() {
print('Android phone is calling...');
}
}
class Ios {
void appleStore() {
print('Apply store');
}
void call() {
print('Ios phone is calling...');
}
}
- 执行
void main(List<String> args) {
var p = Xiaomi();
p.call();
p.playStore();
p.appleStore();
}
Ios phone is calling...
Google play store
Apply store
可以发现后面的覆盖了前面的内容
mixin 不能构造函数
- 加入构造函数
class Android {
Android();
...
}
The class 'Android' can't be used as a mixin because it declares a constructor.
- 加入 mixin 关键字 限定
mixin Android {
// mixin 中不能定义 constructor
...
}
mixin on 限定条件
- 关键字 on 限定 Phone
mixin Android on Phone {
void playStore() {
print('Google play store');
}
@override
void call() {
super.call();
print('Android phone is calling...');
}
}
- with 混入时候,必须先 Phone 才行
错误
class Xiaomi with Android {}
'Android' can't be mixed onto 'Object' because 'Object' doesn't implement 'Phone'.
Try extending the class 'Android'.
正确
class Xiaomi with Phone,Android {}
工厂函数
调用子类
abstract class Phone {
void call();
factory Phone(String type) {
switch (type) {
case "android":
return Android();
case "ios":
return Ios();
default:
throw "The '$type' is not an animal";
}
}
}
class Android implements Phone {
@override
void call() {
print('Android Calling...');
}
}
class Ios implements Phone {
@override
void call() {
print('Ios Calling...');
}
}
void main() {
var android = Phone('android');
var ios = Phone('ios');
android.call();
ios.call();
}
单例模式
class Phone {
static final Phone _single = Phone._internal();
Phone._internal();
factory Phone() {
return _single;
}
void call() {
print('Calling...');
}
}
void main() {
var p1 = Phone();
var p2 = Phone();
print(identical(p1, p2));
Phone().call();
}
减少重复实例对象
class Phone {
int _number;
Phone(this._number);
factory Phone.fromJson(Map<String, dynamic> json) =>
Phone(json['number'] as int);
void call() {
print('Calling $_number...');
}
}
void main() {
var p = Phone.fromJson({"number": 911});
p.call();
}
如果不用工厂函数,就要用类静态方法,这样会有多余的实例对象
库 lib
导入核心库
import 'dart:io';
void main() {
var f = new File('README.md');
var content = f.readAsStringSync();
print(content);
}
# Dart 语言学习示例
导入第三方库
- 编写
pubspec.yaml
dependencies:
dio: ^4.0.6
- 执行拉取包命令
$ dart pub get
- 程序调用
import 'package:dio/dio.dart';
void main() async {
Dio dio = Dio();
Response<String> response =
await dio.get("https://wpapi.ducafecat.tech/products/categories");
print(response.data);
}
[{"id":34,"name":"Bag","slug":"bag","parent":0,"description":" ......
导入自己的 git 仓库
- 编写
pubspec.yaml
dependencies:
uuid:
git:
url: https://github.com/Daegalus/dart-uuid
ref: master
- 执行拉取包命令
$ dart pub get
从 master 分支拉取
导入类文件
- phone.dart
class Phone {
void call() {
print('Phone is calling...');
}
}
class Android {
void playStore() {
print('Google play store');
}
void call() {
print('Android phone is calling...');
}
}
class Ios {
void appleStore() {
print('Apply store');
}
void call() {
print('Ios phone is calling...');
}
}
- 实例
import 'package:dart_learn/phone.dart';
void main() {
var p = Phone();
p.call();
}
Phone is calling...
前缀&别名
import 'package:dart_learn/phone.dart' as pp;
void main() {
var p = pp.Android();
p.call();
p.playStore();
}
Android phone is calling...
Google play store
筛选包内容
import 'package:dart_learn/phone.dart' show Ios;
void main() {
var p = Ios();
p.call();
p.appleStore();
}
Ios phone is calling...
Apply store
hide筛掉某几个包show只使用某几个包
延迟载入
import 'package:dart_learn/phone.dart' deferred as pp;
Future<void> main() async {
await pp.loadLibrary();
var p = pp.Android();
p.call();
p.playStore();
}
Android phone is calling...
Google play store
loadLibrary()方式在需要的时候载入包 可提高程序启动速度 用在不常使用的功能 用在载入时间过长的包
泛型 generics
泛型使用
main(List<String> args) {
var l = <String>[];
l.add('aaa');
l.add('bbb');
l.add('ccc');
print(l);
var m = <int, String>{};
m[1] = 'aaaa';
m[2] = 'bbbb';
m[3] = 'cccc';
print(m);
}
[aaa, bbb, ccc]
{1: aaaa, 2: bbbb, 3: cccc}
容器对象,在创建对象时都可以定义泛型类型。
泛型函数
K addCache<K, V>(K key, V val) {
print('$key -> $val');
return val;
}
main(List<String> args) {
var key = addCache('url', 'https://wiki.doucafecat.tech');
print(key);
}
url -> https://wiki.doucafecat.tech
https://wiki.doucafecat.tech
构造函数泛型
class Phone<T> {
final T mobileNumber;
Phone(this.mobileNumber);
}
main(List<String> args) {
var p = Phone<String>('ducafecat');
print(p.mobileNumber);
}
这是大多数情况下使用泛型的场景,在一个类的构造函数中
泛型限制
- 定义
class AndroidPhone {
void startup() {
print('Android Phone 开机');
}
}
class Phone<T extends AndroidPhone> {
final T mobile;
Phone(this.mobile);
}
- 实例
main(List<String> args) {
var ad = AndroidPhone();
var p = Phone<AndroidPhone>(ad);
p.mobile.startup();
}
Android Phone 开机
通过 extends 关键字 可以限定你可以泛型使用的类型