Dart语言也是一个面向对象的编程语言,它提供了类和基于mixin的继承方式。在Dart语言中几乎所有的对象都是一个类的实例,类的构造器正是提供了构建对象的方法,但是在Dart语言中没有函数、方法或构造器orverloading特性,我们应该如何使用构造器在不同场景下构建对象呢?本文将介绍Dart语言在不同场景下构造器的用法和注意事项。
每一个类都默认提供了一个缺省构造器,缺省构造器没有任何参数,如下图1所示,创建了一个BaseShape类,这个类只拥有一个实例成员description,但是没有显式地提供缺省构造器。图1中第75行代码使用缺省构造器创建了一个BaseShape对象,注意在类BaseShape中,我们并没有定义缺省构造器,而是让系统自动生成一个缺省构造器,通过第75行代码,输出的内容如图2所示。
图1
在下图2中,我们可以看到,BaseShape对象o1的成员description的值为‘base shape’,这就是缺省构造器所完成的工作,它不对实例成员做任何修改。
图2
如果我们定义了缺省构造器,那么,在使用缺省构造器创建对象时将会执行这个构造器中的相应代码。
图3
图3中第68-90行代码定义了缺省构造器BaseShape,缺省构造器中第69行代码设置了description的值为’my default base shape’,之后,我们再次输出o1对象,对应的输出结果为图4所示
图4
这就说明了系统创建的缺省构造器只负责构建出这个类的对象,并不执行额外的代码,如果用户重新定义了一个缺省构造器,那么,使用缺省构造器创建对象时,会执行这个构造器中的代码。
使用构造器创建对象时,通常需要指定类实例中的某些参数,比如上一节BaseShape类中有一个实例成员description,在构建这个类的对象时,通常可以指定description参数,这个类实例成员可以通过构造器的参数传递进来,如下图5所示
图5
图5中第68-70行代码为含有一个参数description的构造器,在构造器体中,第69行代码将参数赋值给了类实例成员description。如果定义了非缺省构造器,那么,就无法再直接使用缺省构造器了,因此,在创建对象时必须使用对应的含有参数的构造器,如图5中第79行代码所示。
通过构造器初始化类实例成员的用法太普遍了,为了简化操作,Dart语言还提供了一种称为初始化形参构造器(initializing formal parameters)的功能,如下图6所示
图6
图6中第68行代码实现了图5中68-70行代码的功能,使用this和类实例成员的名称简化了赋值操作。这种做法也是Dart语言所倡导的,其实在图5中第69行代码Visual Studio Code已经给出提示,建议将其转换为初始化形参构造器。
在本文的开头部分,我们提到了Dart语言是不支持函数overloading的,即同一个作用域下不能有名称相同的函数、方法或构造器,但是在创建对象时,往往是需要根据不同的参数来构建同一个类型的对象,Dart语言为此提供了一种命名构造器(named constructor),如下图7所示
图7
图7中第69-71行代码实现了一个命名构造器,通过“类名.标识”的方式命名一个构造器,图7中类名依旧是BaseShape,其标识(identifier)为empty,这样,我们就在一个类中实现了两个构造器:第68行代码为一个含有参数的构造器,第69行代码为命名构造器。第80行代码通过调用命名方法构建了一个BaseShape对象。通过这种命名构造器,我们就可以创建任意多个不同参数的命名构造器了,达到与其它语言中方法重载(overloading)的目的。
上一节中我们介绍了通过使用命名构造器,我们可以使用不同的参数创建实例对象,但是,通常情况下,我们提供一个功能完备的构造器,而其它的构造器只是通过不同的参数调用这唯一的构造器,Dart语言也提供了这样的功能,称为构造器的重定向功能,如下图8所示。
图8
图8中,我们在BaseShape的类中增加了一个整型成员id,在BaseShape类中定义了3个构造器,第69行代码创建的初始化形参构造器使用了两个参数id和description,第70行和71行代码对构造器进行了重定向,如第70行代码中的this(0, description)和第71行中的this(0,’empty’),这两个重定向构造器都会调用第69行所定义的构造器,所不同的是第70行代码使用了一个description参数,id参数采用默认值0;第71行代码则是没有指定任何参数,使用两个默认值作为构造器的参数。
Dart语言除了提供不同的构造器之外,还提供了一个factory构造器,这个构造器一般会通过设计模式的方式来提供,Dart语言提供这个功能是为了在构建对象时不一定每次都创建新的实例对象,它有可能使用的是缓存中的对象。与其它构造器最显著的区别是:factory构造器不可以使用this访问类实例成员。
图9
图9中第68行代码创建了一个静态成员sInstance,第74-77行代码创建了一个factory构造器,在这个构造器中,首先判断静态成员变量sInstance的当前值是否为null,如果是null值,则创建一个新的BaseShape对象,如果不是null值,则直接返回sInstance的值,而无需再次创建BaseShape对象。
通过以上几个小节的演示,我们可以发现,虽然Dart语言没有提供构造器重载功能,但是与其它高级语言相比,通过使用命名构造器,参数构造器等多种构造途径完成了类似方法重载的功能。没有方法的重载功能,Dart依然可以完成构建对象的多样化操作。
留言与评论(共有 0 条评论) “” |