dart语法1
dart语法2-内置类型
dart语法3-函数
dart语法4-操作符
dart语法5-异常
dart语法6-类
dart语法7-泛型
dart语法8-库
dart语法9-异步
dart语法10-生成器
dart语法11
类
构造函数
//java中写法
class Point {
double x;
double y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
//dart建议写法
class Point {
num x;
num y;
Point(this.x, this.y);
}
命名构造函数
使用命名构造函数可以为一个类实现多个构造函数, 或者使用命名构造函数来更清晰的表明你的意图。
class Point {
num x;
num y;
Point(this.x, this.y);
//命名构造函数
Point.fromJson(Map json) {
x = json['x'];
y = json['y'];
}
}
重定向构造函数
一个重定向构造函数是没有代码的,在构造函数声明后,使用 冒号调用其他构造函数。
class Point {
num x;
num y;
Point(this.x, this.y);
//重定向构造函数,使用冒号调用其他构造函数
Point.alongXAxis(num x) : this(x, 0);
}
初始化列表
在构造函数体执行之前可以初始化实例参数。 使用逗号分隔初始化表达式。
初始化列表非常适合用来设置 final 变量的值。
import 'dart:math';
class Point {
//final变量不能被修改,必须被构造函数初始化
final num x;
final num y;
final num distanceFromOrigin;
//初始化列表
Point(x, y)
: x = x,
y = y,
distanceFromOrigin = sqrt(x * x + y * y);
}
调用超类构造函数
超类命名构造函数不会传递,如果希望使用超类中定义的命名构造函数创建子类,则必须在子类中实现该构造函数。
如果超类没有默认构造函数, 则你需要手动的调用超类的其他构造函数。
调用超类构造函数的参数无法访问 this。
在构造函数的初始化列表中使用 super(),需要把它放到最后。
class Parent {
int x;
int y;
//父类命名构造函数不会传递
Parent.fromJson(x, y)
: x = x,
y = y {
print('父类命名构造函数');
}
}
class Child extends Parent {
int x;
int y;
//若超类没有默认构造函数, 需要手动调用超类其他构造函数
Child(x, y) : super.fromJson(x, y) {
//调用父类构造函数的参数无法访问 this
print('子类构造函数');
}
//在构造函数的初始化列表中使用super(),需要把它放到最后
Child.fromJson(x, y)
: x = x,
y = y,
super.fromJson(x, y) {
print('子类命名构造函数');
}
}
常量构造函数
定义const构造函数要确保所有实例变量都是final。
const关键字放在构造函数名称之前。
class Point2 {
//定义const构造函数要确保所有实例变量都是final
final num x;
final num y;
static final Point2 origin = const Point2(0, 0);
//const关键字放在构造函数名称之前,且不能有函数体
const Point2(this.x, this.y);
}
工厂构造函数
工厂构造函数是一种构造函数,与普通构造函数不同,工厂函数不会自动生成实例,而是通过代码来决定返回的实例对象。
如果一个构造函数并不总是返回一个新的对象,则使用 factory 来定义这个构造函数。
工厂构造函数无法访问this。
class Singleton {
String name;
//工厂构造函数无法访问this,所以这里要用static
static Singleton _cache;
//工厂方法构造函数,关键字factory
factory Singleton([String name = 'singleton']) =>
Singleton._cache ??= Singleton._newObject(name);
//定义一个命名构造函数用来生产实例
Singleton._newObject(this.name);
}
Setter和Getter
每个实例变量都隐含的具有一个 getter, 如果变量不是 final 的则还有一个 setter。
可以通过实行 getter 和 setter 来创建新的属性, 使用 get 和 set 关键字定义 getter 和 setter。
getter 和 setter 的好处是,你可以开始使用实例变量,后来 你可以把实例变量用函数包裹起来,而调用你代码的地方不需要修改。
class Rectangle {
num left;
num top;
num width;
num height;
Rectangle(this.left, this.top, this.width, this.height);
num get right => left + width;
set right(num value) => left = value - width;
num get bottom => top + height;
set bottom(num value) => top = value - height;
}
抽象类
- abstract关键字修饰class
- 继承的方式使用
- 接口的方式使用
不能被实例化,除非定义一个工厂构造函数。
抽象类通常用来定义接口, 以及部分实现。
抽象类通常具有抽象方法,抽象方法不需要关键字,以分号结束即可。
接口方式使用时,需要重写抽象类的成员变量和方法,包括私有的。
一个类可以implement一个普通类。Dart任何一个类都是接口。
一个类可以implement多个接口。
可调用类
实现call()方法可以让类像函数一样能够被调用。
class ClassFunction {
call(String a, String b, String c) => '$a $b $c!';
}
main() {
var cf = new ClassFunction();
var out = cf("dongnao","flutter","damon");
print('$out');
print(cf.runtimeType);
print(out.runtimeType);
print(cf is Function);
}
Mixin
子类没有重写超类A方法的前提下,如果2个或多个超类拥有相同签名的A方法,那么子类会以继承的最后一个超类中的A方法为准。
如果子类自己重写了A方法则以本身的A方法为准。
图片.png
main() {
Bicycle().transport();
Motorcycle().transport();
Car().transport();
//四轮木制脚踏车
WoodenCar().transport();
}
//交通工具类,拥有运输功能
abstract class Transportation {
//运输功能
void transport();
}
//自行车
class Bicycle extends Transportation
with TwoWheelTransportation, LowSafetyIndex, BodyEnergyTransportation {
@override
void transport() {
print(
"自行车:\n动力组件: ${powerUnit()} , 安全指数: ${safetyIndex()} , 动力来源:${energy()}");
}
// String safetyIndex() => "low";
//
// String powerUnit() => "两个轮子";
//
// String energy() => "全靠腿登";
}
//摩托车
class Motorcycle extends Transportation
with TwoWheelTransportation, LowSafetyIndex, GasolineEnergyTransportation {
@override
void transport() {
print(
"摩托车:\n动力组件: ${powerUnit()} , 安全指数: ${safetyIndex()} , 动力来源:${energy()}");
}
// String safetyIndex() => "low";
//
// String powerUnit() => "两个轮子";
//
// String energy() => "汽油";
}
//汽车
class Car extends Transportation
with
FourWheelTransportation,
MiddleSafetyIndex,
GasolineEnergyTransportation {
@override
void transport() {
print(
"汽车:\n动力组件: ${powerUnit()} , 安全指数: ${safetyIndex()} , 动力来源:${energy()}");
}
// String safetyIndex() => "middle";
//
// String powerUnit() => "四个轮子";
//
// String energy() => "汽油";
}
//双轮交通工具
class TwoWheelTransportation {
String powerUnit() => "两个轮子";
}
//四轮交通工具,一般来说安全性能为中
class FourWheelTransportation {
String powerUnit() => "四个轮子";
}
//安全指数中等的交通工具儿
class MiddleSafetyIndex {
String safetyIndex() => "middle";
}
//安全指数低的交通工具儿
class LowSafetyIndex {
String safetyIndex() => "low";
}
//人力发动机
class BodyEnergyTransportation {
String energy() => "全靠腿登";
}
//汽油能源交通工具
class GasolineEnergyTransportation {
String energy() => "汽油";
}
//四轮木制脚踏车
class WoodenCar extends Car
// with LowSafetyIndex, BodyEnergyTransportation
//implements LowSafetyIndex, BodyEnergyTransportation
{
@override
void transport() {
print(
"四轮木制脚踏车:\n动力组件: ${powerUnit()} , 安全指数: ${safetyIndex()} , 动力来源:${energy()}");
}
}
//顺序问题
//如果2个或多个超类拥有相同签名的A方法,那么子类会以继承的最后一个超类中的A方法为准。
//当然这是子类没有重写A方法的前提下,如果子类自己重写了A方法则以本身的A方法为准
class A {
String getMessage() => 'A';
}
class B {
String getMessage() => 'B';
}
class P {
String getMessage() => 'P';
}
class AB extends P with A, B {}
class BA extends P with B, A {}
class C extends P with B, A {
String getMessage() => 'C'; //优先级最高的是在具体类中的方法。
}
class CC extends P with B implements A {
} //这里的implement只是表明要实现A的方法,这个时候具体实现是再B中mixin了具体实现
网友评论