extends
继承。 Dart里没有多继承。根类是Object.
abstract class StatefulWidget extends Widget
abstract class StatelessWidget extends Widget
mixin ( With)
混入(mixin)。通过非继承的方式使用另一个类的函数。
//flutter 里用到混用的类
abstract class Diagnosticable with DiagnosticableMixin
示例
class A {
a(){
print("this is a function!");
}
}
mixin aa {
aaFunction(){
print("this is aa function! ha ha !");
}
}
class Aa with aa,A
{
}
//调用
Aa()
..a()
..aaFunction();
implements
实现。dart里没有interface 关键字。implements 与OC 的 delegate 类似。
eg :flutter 里的Element 和 List。 BuildContext 和 Iterable 都抽象类(abstract)只是提供接口,然后在 implements 的类里去实现。Flutter里用到的 implements的类
abstract class Element extends DiagnosticableTree implements BuildContext
//将BuildContext这个类的成员都看做是接口的定义
abstract class List<E> implements EfficientLengthIterable<E>
abstract class EfficientLengthIterable<T> extends Iterable<T>//里实现了快速遍历等方法
实现implements类的方法前加 @override
// Element 里实现的BuildContext 的方法
@override
InheritedWidget inheritFromElement(InheritedElement ancestor, { Object aspect }) {
assert(ancestor != null);
_dependencies ??= HashSet<InheritedElement>();
_dependencies.add(ancestor);
ancestor.updateDependencies(this, aspect);
return ancestor.widget;
}
class AB implements B ,则A里必须实现B里的全部方法,即使B类里有实现该方法。Missing concrete implementation of B
而mixin的类则不必需实现,如实现了则优先调用ABclass里实现的方法
class A {
a(){
print("this is a function!");
}
}
mixin aa {
aaFunction(){
print("this is aa function! ha ha !");
}
}
class B {
b(){
print("this is b ! b B");
}
bB(){
print("this B class bB Function !");
}
}
abstract class BB {
bb();
}
class AB with aa,A implements BB, B
{
@override
a() {
print("this is AB class a Function !");
}
@override
bb() {
print("this is Aa class bb Function !");
}
@override
b() {
print("this is Aa class b Function !");
}
@override
bB() {
print("this is Aa class bB Function !");
}
}
调用结果
AB()
..a()
..aaFunction()
..b()
..bb();
//打印
I/flutter (29103): this is AB class a Function !
I/flutter (29103): this is aa mixin function! ha ha !
I/flutter (29103): this is Aa class b Function !
I/flutter (29103): this is Aa class bb Function !
以上三种关系可以同时存在,但是有前后顺序: extends -> with (mixin) -> implements

<>
泛型。里为指定的泛型的类型
eg. 我们去子类化声明State类的方式为
class TabBarState extends State <TableBarPage>
///<TableBarPage> 表明TabBarState 的父类State是用来表示TableBarPage的状态
还有就是用于List里的泛型,与OC里用法一致
List<Widget> pages = List<Widget>();///List里为Widget 或其子类
用Extension对类进行扩展
一般情况要扩展一个类,需要继承这个类,这是在大多数java或者其他面向对象语言中要做的事情。
但是有些时候扩展类并不是特别好用,首先在有些语言中,有些类是禁止被扩展的。即使可以被扩展,但是扩展之后的类是一个新的类,而不是原来的父类,所以在使用的过程中可能会出现一些类型转换的问题。
那么在dart中是怎么解决这个问题的呢?
dart中extension的使用(2.7的新特性)
dart在2.7之后,引入了extension,用来对类的方法进行扩展。
到底怎么扩展呢?我们举个例子.
我们可以将字符串转换为int,通过调用int的parse方法,如下所示:
int.parse('18')
但是通过int类来进行转换通常不太直观,我们希望能够在String类中提供一个toInt的方法,可以直接调用,将字符串转换成为int。
'18'.toInt()
但是很遗憾,String并没有提供toInt的方法,所以我们可以通过extension来对String进行扩展:
extension StringToNumber on String {
int toInt() {
return int.parse(this);
}
// ···
}
如果这个文件的名字叫做string_to_number.dart,那么我们可以这样使用:
import 'string_to_number.dart';
// ···
print('18'.parseInt());
dart中方法扩展最为方便的是,你只要引入对应的lib,使用的时候甚至都不知道在使用lib的扩展。
当然,并不是所有的类都可以使用extention进行扩展。比如dynamic类型就不能进行扩展。
但是使用var类型,只要该类型可以被推断出来,那么就可以使用extention扩展。
API冲突
既然可以对lib进行扩展,那么就有可能出现API冲突的情况。那么怎么解决API冲突呢?
比如我们需要使用两个lib扩展文件,extention1.dart和extention2.dart.但是两个扩展文件中都定义了parseInt方法对String进行扩展。
如果同时引用的话,就会出现问题。
这时候可以使用show或者hide来限制具体使用哪一个扩展文件的中的方法。
import 'extention1.dart';
import 'extention2.dart' hide StringToNumber2;
print('18'.parseInt());
还有一种情况就是显示调用extension,如下所示:
import 'extention1.dart';
import 'extention2.dart';
print(StringToNumber('18').parseInt());
print(StringToNumber2('18').parseInt());
通过extention的名字来进行区分。
如果两个extention的名字也相同的话,那么可以通过prefix来进行区分:
import 'extention1.dart';
import 'extention2.dart' as ext2;
print(StringToNumber('18').parseInt());
print(ext2.StringToNumber('18').parseInt());
extention的实现
实现扩展很简单,实现语法如下:
extension <extension name> on <type> {
(<member definition>)*
}
下面是一个扩展String的例子:
extension NumberParsing on String {
int parseInt() {
return int.parse(this);
}
double parseDouble() {
return double.parse(this);
}
}
extension还可以扩展泛型参数:
extension MyFancyList<T> on List<T> {
int get doubleLength => length * 2;
List<T> operator -() => reversed.toList();
List<List<T>> split(int at) => [sublist(0, at), sublist(at)];
}
上面的实现是对List 进行扩展,添加了getter,操作符和split方法。
可选类型扩展的例子:
final String? a = null;
DDLog(a.runtimeType); // Null
DDLog(a.or(() => "456")); // 456
DDLog(a.or((){
return "111";
})); // 111
extension GetDynamicExt<T> on T {
/// 返回可选值或者 `else` 闭包返回的值
/// 例如. nullable.or(else: {
/// ... code
/// })
T or(T Function() block) {
return this ?? block();
}
}