scala继承类和java一样用关键字extends,子类可以定义超类没有的字段和方法,或重写超类的方法。
声明类为final它就不能被继承,还可以将方法或字段声明为final,以确保它们不会被重写。 和Java不同,Java中final声明常量,类似Scala中的val。
Scala中重写非抽象方法必须使用override修饰符;
Scala中调用超类的方法和Java一样用super;
if (p.isInstanceOf[String]) { val s = p.asInstanceOf[String] }
如果p是null,返回false
如果p不是String,p.asInstanceOf[String]将抛异常。
if (p.getClass() == classOf[String]) { val s = p.asInstanceOf[String] }
p match { case s: String => // String do case _ => //not String do }
可以将字段或方法声明为protected,这样成员可以被任意子类看到,但不能从其它位置看到。
访问对象仅限当前对象protected[this], 类似于private[this]
只有主构造方法才能调用超类的构造方法,辅构造方法永远不可能调用超类的构造方法;
调用超类的构造方法也和类定义交织在一起:
class Employee(val name: String, age: Int) extends Person(age) {
}
def meet(p: Person { def greeting: String }) = {
}
val alien = new Person(2) {
def greeting = "Greetings!"
}
meet(alien)
和Java一样:
使用abstract标记类为抽象类;
不能实例化;
和Java不一样:
抽象方法没有定义方法体,不需要abstract标记;
子类重写超类的抽象方法时,不需要使用override关键字
指没有初始值的字段
子类重写超类的字段时,不需要使用override关键字
构造顺序和提前定义:
class Creature {
val range = 10
val env = new Array[Int](range)
}
class Ant extends Creature {
override val range = 2
}
object TestAnt extends App {
val ant = new Ant()
println(ant.env.length) // 结果为0
println(ant.range) // 结果为2
}
因为先构造Creature;构造env时调用range(),而Ant没有实例化返回0;然后构造Ant。
解决方法:
提前定义
class Ant extends {
override val range = 2
} with Creature {
}