10.1继承类
和Java一样使用extends关键字,在定义中给出子类需要而超类没有的字段和方法,或者重写超类的方法。
如果类声明为final,他讲不能被继承。
如果单个方法声明为final,将不能被重写。
10.2重写方法
重写一个非抽象方法需要用override修饰符。
调用超类的方法使用super关键字
10.3类型检查和转换
要测试某个对象是否属于某个给定的类,可以用isInstanceOf方法。
用asInstanceOf方法将引用转换为子类的引用。
classof获取对象的类名。
10.4受保护的字段和方法
protected声明字段和方法,子类可见,所属包不可见。
10.5超类的构造
只有主构造器才能调用超类的构造器,构造器的参数,传入了超类的构造函数。
Scala不能通过super(a)这种方式调用超类的构造函数。
10.6重写字段
子类改写父类或者抽象父类的字段,通过以下方式:
注意如下限制(同时参照表8-2):
·def只能重写另一个def。
val只能重写另一个val或不带参数的def。
·var只能重写另一个抽象的var(参见8.8节“抽象类”)。
10.7匿名子类
可以通过包含带有定义或重写的代码块的方式创建一个匿名的子类:
匿名类的变量类型为:Person{def greeting:String}这是一个结构类型
10.8抽象类
可以通过abstract关键字标记不能被实例化的类。
方法不用标记abstract,只要省掉方法体即可。
类可以拥有抽象字段,抽象字段就是没有初始值的字段。
子类实现抽象方法不需要override。
10.9构造顺序和提前定义
当子类重写了父类的方法或者字段后,父类又依赖这些字段或者方法初始化,这个时候就会出现问题,比如:
解决这个问题,可以有3种方法:
1)将val声明为final,这样子类不可改写。
2)将超类中将val声明为lazy,这样安全但并不高效
3)可以使用提前定义语法,可以在超类的构造器执行之前初始化子类的val字段,
10.10Scala继承层级
所有其他类都是AnyRef的子类,AnyRef是Java或.NET虚拟机中Object类的同义词。
AnyVal和AnyRef都扩展自Any类,而Any类是整个继承层级的根节点。
Any类定义了isInstanceOf、aslnstanceOf方法,以及用于相等性判断和哈希码的方法,我们将在8.12节中介绍。
AnyVal并没有追加任何方法。它只是所有值类型的一个标记。
AnyRef类追加了来自Object类的监视方法wait和notify/notifyAll。同时提供了一个带函数参数的方法synchronized。这个方法等同于Java中的synchronized块。例如:
所有的Scala类都实现ScalaObject这个标记接口,这个接口没有定义任何方法。
在继承层级的另一端是Nothing和Null类型。
Null类型的唯一实例是null值。你可以将l赋值给任何引用,但不能赋值给值类型的变量。举例来说,我们不能将lnt设为null。这比Java更好,在Java中我们可以将Integer包装类引用设为null。
Nothing类型没有实例。它对于泛型结构时常有用。举例来说,空列表Nl的类型是List[Nothing],它是List[T]的子类型,T可以是任何类。
import org.scalatest.FunSuite
class Chapter09Test extends FunSuite {
test("core01") {
//继承类
}
test("core02") {
//重写方法
}
test("core03") {
//类型检查和转换
val r = scala.math.random
val p = if (r < 0.1) {
new Array(1)
} else {
new scala.collection.mutable.ArrayBuffer[Int]()
}
//某个对象是否属于某个给定的类
// if (p.isInstanceOf[Array]) {
// //用asInstanceOf方法将引用转换为子类的引用
// val s = p.asInstanceOf[Array]
// }
//classof获取对象的类名
// if (p.getClass == classOf[p.type]) {
// println(123)
// }
}
test("core04") {
//protected
}
test("core05") {
//超类的构造
//只有主构造器才能调用超类的构造器,构造器的参数,传入了超类的构造函数。
}
test("core06") {
//重写字段
}
test("core07") {
//匿名子类
}
test("core08") {
// 抽象类
}
test("core09") {
// 构造顺序和提前定义
}
test("core10") {
println(111)
}
}
//继承
class Person {
var name = ""
//重写
override def toString: String = getClass.getName
}
class Employee extends Person {
val salary = 0.0
override def toString: String = super.toString
//protected声明字段和方法,子类可见,所属包不可见
protected var empno = 0
}
//超类的构造举例
class Person1(val name: String, val age: Int) {
override def toString = getClass.getName + "[name=" + name +
",age=" + age + "]"
}
class Employee1(name: String, age: Int, val salary: Double) extends
Person1(name, age) {
override def toString = super.toString + "[salary=" + salary + "]"
}
//子类重写父类的字段
abstract class Person2 {
def id: Int
}
class Student(override val id: Int) extends Person2
//抽象类
abstract class AbstractPerson(val pname: String) {
//抽象类的字段 方法
val id: Int
var name: String
def idString: Int
}
// 提前定义
class Creature {
val range: Int = 10
val env: Array[Int] = new Array[Int](range)
}
class Bug extends {
// 提前定义
override val range = 3
} with Creature