默认构造函数
不声明构造函数,则提供默认的无参构造,和java类似。
普通构造函数
class Point{
num x,y;
//this指当前实例,Dart中,只有名称冲突时才使用它,否则,Dart的代码风格是要省略this的。
Point(num x,num y){
this.x = x ;
this.y = y ;
}
}
另外一种构造方法写法:(减少代码量)
class Point{
num x,y;
Point(this.x,this.y);
}
构造函数不是继承
如何理解这句话?我们看中文翻译过来的语句:
"子类不从父类继承构造函数(下面说到的命名函数也不会继承)。没有声明构造函数的子类只有默认的构造函数(没有参数,没有名称)而不是从父类继承的构造函数。"
怎么样去理解呢?
直接上代码吧:
class Vehicle{
Vehicle(){
print("super Constructor") ;
}
Vehicle.get(){
print("super Run") ;
}
Vehicle.create(){
print("super create") ;
}
}
class Audi extends Vehicle{
Audi(){
print("Audi Constructor") ;
}
Audi.get():super.get(){
print("Audi run");
}
Audi.create(){
print("Audi create") ;
}
}
//调用
Audi audi0 = Audi() ;
Audi audi1 = Audi.create() ;
Audi audi2 = Audi.get() ;
//打印结果
I/flutter ( 660): super Constructor
I/flutter ( 660): Audi Constructor
I/flutter ( 660): super Constructor
I/flutter ( 660): Audi create
I/flutter ( 660): super Run
I/flutter ( 660): Audi run
总结:
1。无论是普通的构造方法,还是命名构造方法,都会默认地先调用父类的无参构造函数。
2。如果子类有特有的构造函数,会先调用父类的无参默认的构造函数,再调用子类的特有构造。
3。如果想要调用父类的特定的构造函数,需要使用双引号:super来指定。
简而言之:所有的构造函数,如果不指定,只会调用父类默认的无参构造。
命名构造函数
class Point{
num x , y ;
Point(this.x , this.y) ;
Point.origin(){
this.x = 10 ;
this.y = 10 ;
}
//构造参数为实例变量直接赋值
Point.rect(this.x ,this.y) ;
void pointPrint(){
print('x = $x , y = $y ');
}
}
//调用
Point p = Point.origin() ;
p.pointPrint();
为什么要使用命名函数呢?
简单理解:为了可读性。比如上面的示例中的两个命名构造方法:origin()和rect(),可以清晰地看出,origin是为了产生某个点,而rect是为了构造一个边距。这就是语言特性。
初始化列表
还可以在构造函数主体运行之前初始化实例变量。初始值设定项用逗号分开。
Point.fromJson(Map<String, num> json)
: x = json['x'],
y = json['y'] {
print('In Point.fromJson(): ($x, $y)');
}
//注意:初始化器的右边部分中无法访问this关键字。
构造函数重定向,这个使用应该比较多
如在java中,我们常用以下的使用方法:
public class Rect{
private int x ,y , width ,height ;
public Rect(int width ,int height)
{
return this(0,0,width ,height);
}
public Rect(int x , int y ,int width ,int height){
super();
this.x = x ;
this.y = y ;
this.width = width ;
this.height = height ;
}
}
那么在Dart中我们如何实现这种构造呢?
class Rect{
num x ,y , wid , hei ;
Rect(this.x , this.y ,this.wid ,this.hei);
Rect.withSize(num width,num height) : this(0 , 0 , width ,height) ;
}
注意〜〜〜!!!
在Dart中,只能有一个非命名构造器:即如下是不对的,会报错:
class ConstructurText{
String str ;
num age ;
ConstructurText(this.str) ;
//ConstructurText(this.age) ; //这一行会报错:the default constructor is already defined
ConstructurText.age(this.age) ;//我们改成这样就可以了
}
常量构造函数:(单例)
我们先看一下文档中的介绍:
如果您的类生成的对象不会改变,您可以使这些对象成为编译时常量。为此,定义一个const构造函数,并确保所有实例变量都是final的。
class ImmutablePoint {
static final ImmutablePoint origin = const ImmutablePoint(0, 0);
final num x, y;
const ImmutablePoint(this.x, this.y);
}
这不就是单例嘛!好吧,这个我们不多说了,记住吧。
工厂构造函数(池子 )
我们同样地,先看一下文档的介绍:
在实现构造函数时使用factory关键字,该构造函数并不总是创建类的新实例。例如,工厂构造函数可以从缓存返回实例,也可以返回子类型的实例。
以下示例演示工厂构造函数从缓存返回对象:
class Logger {
final String name;
bool mute = false;
// _cache is library-private, thanks to
// the _ in front of its name.
static final Map<String, Logger> _cache = <String, Logger>{};
factory Logger(String name) {
if (_cache.containsKey(name)) {
return _cache[name];
} else {
final logger = Logger._internal(name);
_cache[name] = logger;
return logger;
}
}
Logger._internal(this.name);
void log(String msg) {
if (!mute) print(msg);
}
}
//调用
var logger = Logger('UI');
logger.log('Button clicked');
注意:工厂构造函数不能访问this关键字。
好了,这个主要是用来做一个缓存使用的,我们也记住吧,使用场景基本上是用于搭建框架,所以一般在搭建框架的时候,使用一次以后基本不会用了,这个也同上面“常量构造函数“一样,记住。
网友评论