构造函数
默认构造函数
Java
- 在Java中,如果不自行声明构造函数时,类会自动生成一个无参构造函数。如果声明了有参构造函数之后就不会有默认的无参构造函数,此时的无参构造函数需要显示声明。
dart
- 在dart中,如果不自行声明构造函数时,类会自动生成一个默认构造函数(匿名的无参函数),默认构造函数没有参数并会调用父类的无参构造函数。
- 如果声明了构造函数(无论是否有参)之后,默认构造函数就不会再存在,除非你显式声明。
多个构造函数
Java
Java中的构造函数个数是由参数决定的,根据参数的不同会创建不同的构造函数。
在Java中,一个类最多只能有一个无参构造函数和一个或多个有参构造函数。
dart
而dart中的构造函数个数是由命名构造函数决定的。
在声明了构造函数之后,dart可以用命名构造函数声明多个构造函数,有参无参,参数是否一样都无所谓。如果不使用命名构造函数,则dart中,类只会有一个构造函数
class IsCase{
late int i ;
late int j ;
IsCase(this.i, this.j) : super(90);
/* 命名构造函数 */
IsCase.forName(this.i,this.j):super(80);
IsCase.forSet()){
i = 100;
j = 900;
}
}
继承父类
Java
在Java中,子类会自动继承父类的无参构造函数,除非父类只有有参构造函数,那么子类就不会自动继承任何构造函数。
dart
在dart中,如果父类中没有匿名无参的构造函数, 则需要手工调用父类的其他构造函数。 在当前构造函数冒号 (:
) 之后,函数体之前,声明调用父类构造函数。
class IsCase extends FaCase{
late int i ;
late int j ;
IsCase(this.i, this.j) : super(90);
/* 命名构造函数 */
// 构造函数的名字 ClassName.identifier
IsCase.forName(this.i,this.j):super(80);
IsCase.forSet():super(70){
i = 100;
j = 900;
super.a = 9999;
}
}
class FaCase{
int a = 100;
FaCase(this.a);
void faPrint(){
print("FaCase里的变量=$a");
}
}
继承
相同点
- Java 和 dart 都是单继承,并且一个类可以实现多个接口。
- 都是用extends关键字
不同点
- 对于多继承的支持不同,Java是单继承,但是它可以利用接口来实现类似多继承的效果
- 而在Dart中,可以使用mixins来实现多个接口,通过使用
with
关键字,一个类可以使用一个或多个mixins,并继承它们的方法和属性。通过使用with
关键字,一个类可以使用一个或多个mixins,并继承它们的方法和属性。
抽象类
共同点
- 抽象类不可以被实例化,但它的子类可以被实例化
- 抽象类和普通类一样,都有成员变量、构造器和方法。
- Java和dart中的抽象方法都是没有具体实现的,抽象类的子类必须重写所有的抽象方法,dart中还需要重写抽象变量。Dart中的抽象变量本质上是抽象的getter和setter方法,需要在子类中进行具体的实现。
不同点
- Java中没有抽象变量,而dart中有。抽象变量在Dart中的定义方式是在变量前加上
abstract
关键字。 - Java中的抽象方法必须加上abstract关键字,而dart中的抽象方法不用加,只需要没有具体实现就可以。
接口
- Dart中没有interface关键字来定义接口,但是普通类和抽象类都可以作为接口被实现,都使用implements关键字进行实现。
- Java可以定义接口,使用
implements
关键字来实现多个接口。
继承和实现的区别
- 继承只会重写抽象类中的抽象方法
- 实现会重写抽象类中的变量、方法(抽象、非抽象)
异常
捕获异常
try / on / catch / on…catch及finally 块
try
块
包裹可能出现异常的代码
catch块
捕获异常可以避免异常继续传递(除非重新抛出( rethrow )异常)。 可以通过捕获异常的机会来处理该异常,需要指定异常类型时使用on
块。如果没有指定捕获的异常类型,则会捕获所有的异常
catch
块 捕获异常对象,进而进行处理。catch()
函数可以指定1到2个参数, 第一个参数为抛出的异常对象, 第二个为堆栈信息 ( 一个 StackTrace 对象 )。- 如果仅需要部分处理异常, 那么可以使用关键字
rethrow
将异常重新抛出。
on块
- on…catch块:on和catch可以同时使用 ,也可以单独分开使用。 使用
on
来指定异常类型, 使用catch
来 捕获异常对象,只捕获跟在 on 后的异常类型。
finally 块
- 不管是否抛出异常,
finally
中的代码都会被执行。 如果catch
没有匹配到异常, 异常会在finally
执行完成后,再次被抛出 - 任何匹配的
catch
执行完成后,再执行finally
try {
res = x ~/ y;
} on IntegerDivisionByZeroException {
print('不能除以零');// output:不能除以零
}catch (e) {
print(e);
}finally{
print("总是执行,不顾异常");
}
- 在这段代码中,on语句指定了捕获IntegerDivisionByZeroException类型的异常,并执行了相应的处理语句。
- 如果发生除以零的异常,程序会执行on语句中的print语句,并跳过catch语句。
- 如果发生其他类型的异常,catch语句会捕获并执行相应的处理语句。
- finally语句总是会执行,不管是否发生异常。
自定义异常
Dart中的每个异常类型都是内置类 Exception
的子类型。Dart可以通过扩展现有异常来创建自定义异常。
// 自定义异常
class numNot implements Exception {
String errMsg() => "数字不能<100";
}
抛出异常
使用throw
void checkErro(int a){
if(a <100){
throw numNot();
}
}
上述代码的意思:当参数a的大小 <100 时,抛出自定义的异常。
完整代码:
void main() {
// 异常例子1
errorCase1();
// 异常例子2
try{
checkErro(23);
}on numNot catch(e){
print("错误信息:${e.errMsg()}");
}
}
// 异常例子1
void errorCase1(){
int x = 12;
int y = 0;
int res;
try {
res = x ~/ y;
} on IntegerDivisionByZeroException {
print('不能除以零'); // output:不能除以零
} catch (e) {
print(e);
} finally {
print("总是执行,不顾异常");
}
}
void checkErro(int a){
if(a <100){
throw numNot();
}
}
// 自定义异常
class numNot implements Exception {
String errMsg() => "数字不能<100";
}