目录
摘要
继承,重写方法,类型检查,类型转换,protected,重写字段和方法,鸭子类型与匿名子类,抽象类
继承
扩展类
- 与 Java 一样使用
extends
关键字 - 子类构造函数需要实现父类的构造函数
- 将类声明为 final,则该类不能被扩展
- 将方法或字段声明为 final,则不能被重写
- 由于辅助构造器必须调用主构造器或其它辅助构造器,所以辅助构造器永远不可能直接访问父类的构造器
class Person(val name: String) {}
class Employee(name: String, salary: Int) extends Person(name) {}
重写方法
- 重写非抽象方法时必须加上
override
关键字 - 调用超类方法时也是使用
super
关键字
override def toString = super.toString + getClass.getName()
类型检查和转换
isInstanceOf
用于执行类型检查
asInstanceOf
用于执行类型转换
def person = new Person("Jane")
def emp1 = new Employee("Jane", 30)
//类型检查
if (emp1.isInstanceOf[Person]) {
//类型转换
val e = emp1.asInstanceOf[Person]
println(e) //Employee[name=Jane][salary=30]
}
如果需要判断不包含子类的指定类型,则需要使用下述判断方法
if (emp1.getClass == classOf[Person]) {
println("is Person.class")
} else {
println("not Person.class") //not Person.class
}
protected
protected
修饰的成员可以被子类访问,但是不能被其它位置的类(包括同包的其它类)访问。- 如果要让同包的其它类访问,需要使用包修饰符。
protected[this]
可以将访问权限限定在当前对象
//限定子类
protected def info = name
//限定子类 + 同包的类
protected[_14_inherit] def info2 = name
重写字段和方法
def
可以重写def
val
可以重写val
或无参的def
var
只能重写抽象的var
匿名子类与鸭子类型
鸭子类型用于参数类型中。任何拥有此鸭子类型特性的类都可以作为参数传递给该方法,而不必使用继承这种不够灵活的特性。
//定义一个匿名子类的对象,实际是定义了一个结构类型
val anonymousPerson = new Person("Tom") {
def greeting = "hello world"
}
//鸭子类型,只有符合此结构类型的子类对象才可以调用此方法
def meet(p: Person {def greeting: String}): Unit = {
println(p.name + " " + p.greeting)
}
以上只要是 Person
或其子类且拥有 greeting
函数的类都可以作为参数传递,如果定义时去掉类型 Person
,则所有拥有 greeting
函数的类都可以被传递。
抽象类
抽象类可以包含未初始化的各种字段和方法,且重写时无需加上 override
关键字
abstract class Shape(val name:String) {
val int:Int
def height:Int
def width:Int
def getArea(): Int
}
Scala 的继承层级
- Any 包含 AnyVal 和 AnyRef
- AnyVal 包含所有值变量 (Unit, Boolean, Int 等)
- AnyRef 包含 ScalaClasses 和 JavaClasses
- 不能将 null 赋给任何值变量(java 允许赋给包装类)