购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.6 抽象类和特质

1.6.1 抽象类

Scala的抽象类使用关键字abstract定义,具有以下特征:

● 抽象类不能被实例化。

● 抽象类中可以定义抽象字段(没有初始化的字段)和抽象方法(没有被实现的方法),也可以定义被初始化的字段和被实现的方法。

● 若某个子类继承了一个抽象类,则必须实现抽象类中的抽象字段和抽象方法,且实现的过程中可以添加override关键字,也可以省略。若重写了抽象类中已经实现的方法,则必须添加override关键字。

例如,定义一个抽象类Person,代码如下:

定义一个普通类Teacher,并继承抽象类Person,实现Person中的抽象字段和抽象方法,并重写方法eat(),代码如下:

定义一个测试对象,调用Teacher类中的方法,代码如下:

输出结果如下:

姓名:王丽
年龄:28
地址:北京
擅长讲课
爱吃中餐

需要注意的是,上述Teacher类中speak()方法的地址字段(address)是从父类(抽象类Person)中继承而来的。由于该字段在Person中有初始化值,不是抽象字段,若需要在Teacher类中修改该字段的值,则可以在Teacher类的构造函数或其他方法中使用this.address对其重新赋值。例如,将地址改为“上海”,可以使用以下代码:

this.address="上海"

由于Person类中的address字段使用var修饰,而Scala不允许对抽象类中var修饰的非抽象字段进行重写,因此在Teacher类中对address字段进行重写将报编译错误,除非该字段在Person类中的声明是不可变的,即使用val修饰。

1.6.2 特质

Scala特质使用关键字trait定义,类似Java 8中使用interface定义的接口。特质除了有Java接口的功能外,还有一些特殊的功能。下面分别进行讲解。

Scala特质中,字段和方法的定义与Scala抽象类一样,可以定义抽象字段和抽象方法、非抽象字段和非抽象方法。例如以下代码定义了一个特质Pet:

类可以使用关键字extends实现特质,但必须实现特质中未实现的字段和方法(抽象字段和抽象方法),这一点与继承抽象类是一致的。例如以下代码定义了一个普通类Cat,实现了上述特质Pet:

如果需要实现的特质不止一个,那么可以通过with关键字添加额外特质,但位于最左侧的特质必须使用extends关键字。例如,类Dog同时实现了特质Pet、Animal和Runable,代式如下:

trait Animal{
}
trait Runable{
}
//类Dog实现了3个特质
class Dog extends Pet with Animal with Runable{
  //省略...
}

在类实例化的时候,也可以通过with关键字混入多个特质,从而使用特质中的方法。例如以下代码定义了两个特质Runable、Flyable和一个类Bird:

//定义两个特质
trait Runable{
  def run=println("会跑")
}
trait Flyable{
  def fly=println("会飞")
}
//定义一个类
class Bird{
}

在类Bird实例化时混入特质Runable和Flyable,代码如下: l7HJ+2C1KVvtddN682fHvIKFI2DycYYNDpyVM/Kyxcjrin0z/ULWnpa0nWA3cfDn

val bird=new Bird() with Runable with Flyable
bird.run //输出结果“会跑”
bird.fly //输出结果“会飞”
点击中间区域
呼出菜单
上一章
目录
下一章
×