/**
* 第10章 继承
*/
//########################### 10.1 继承类和继承方法重写 #################################
/**
* 使用extends关键字继承
* 用final关键字修饰的类不能被继承
* 用final关键字修饰的方法不能被重写
*/
class Person {
var name = ""
def myName() = name
//方法重写
override def toString = name
}
//继承
class Employee extends Person {
var salary = 0.0
def descriptio = "An employee with name " + name + " and salary " + salary
//方法重写
override def myName(): String = "xxx"
}
//########################### 10.2 类型检查和转换 #################################
val em = new Employee()
em.isInstanceOf[Person] //判断类型
em.asInstanceOf[Person] //转为子类的引用
val p = classOf[Person] //获取对象的类名
//########################### 10.3 受保护的字段和方法 #################################
/**
* 用关键字protected修饰的字段和方法,子类可见,所属包的其他类不可见
*/
//########################### 10.4 超类的构造 #################################
/**
* 只有主构造器才能调用超类的构造器
* Scala不能通过super(a)方式来调用超类的构造函数
*/
class Person2(val name: String, val age: Int) {
override def toString = getClass.getName + "[name = " + name + ",age = " + age + "]"
}
//构造参数传入了超类构造函数的参数name2、age2
class Employee2(name2: String, age2: Int, val salary: Double) extends Person2(name2, age2) {
override def toString = super.toString + "[salary = " + salary + "]"
}
//########################### 10.5 重写字段 #################################
/**
* 子类改写父类或者抽象父类的字段,通过以下2种方式
*/
abstract class Person3 {
def id: Int //抽象的方法,没有方法体
}
class Student3(override val id: Int) extends Person3 {
println(id)
}
class SecreAgent extends Person3 {
override val id = scala.util.Random.nextInt
println(id)
}
/**
* 注意如下限制
* def 只能重写另一个def
* val只能重写另一个val或者不带参数的def
* var只能重写另一个抽象的var(即未被赋值的var)
*/
//########################### 10.6 匿名子类 #################################
class Person4(val name: String) {
override def toString = getClass.getName + "[name=" + name + "]"
}
/**
* 匿名类的变量类型为:Person4{def greeting: String; val greetin2: String} 这是一个结构类型
*/
val alien = new Person4("Fred") {
def greeting = "Greeting,Earthling ! My name is Fred"
val greetin2 = "Greeting,Earthling ! My name is Fred"
}
//########################### 10.7 抽象类 #################################
/**
* 抽象类:可以通过abstract关键字标记不能被实例化的类.
* 抽象方法:不用标记abstract,只要省掉方法体即可
* 抽象字段:类可以拥有抽象字段,抽象字段就是没有初始值的字段
*/
abstract class Person5(val pname: String) {
//No initializer--this is an abstract field with an abstract getter method
val id: Int
//Another abstract field,with abstract getter and setter methods
var name: String
//No method body -- this is an abstract method
def idString: Int
}
class Employee5(pname: String) extends Person5(pname) {
val id = 5
var name = ">>>"
def idString: Int = pname.hashCode() //ovveride keyword not required
}
//########################### 10.8 构造顺序和提前定义 #################################
/**
* 当子类重写了父类的方法或者字段后,父类又依赖这些字段或者方法初始化,这个时候就会出现问题,比如:
*/
class Creature {
val range: Int = 10
val env: Array[Int] = new Array[Int](range)
}
class Ant extends Creature {
override val range = 2
}
val Ant = new Ant
Ant.env.size //0
Ant.range //2
/**
* 解决3种方法:
* 1.将val生命为final,这样子子类不可改写(range=10,env.size=10)
* 2.将超类和子类中的val生命为lazy,这样安全但并不高效(range=2,env.size=2)
* 3.可以使用提前定义语法,可以在超类的构造器执行之前初始化子类的val字段
*/
class Bug extends {
override val range = 3
} with Creature
val bug = new Bug
bug.env.size //3
bug.range //3
//########################### 10.9 Scala继承层级 #################################