1.重写方法
class Person {
var name: String = "tom"
def printName() { //输出名字
println("Person printName() " + name)
}
def sayHi(): Unit = {
println("sayHi...")
}
}
//这里继承Person
class Emp extends Person {
//这里需要显式的使用override
override def printName() {
println("Emp printName() " + name)
//在子类中需要去调用父类的方法,使用super
super.printName()
sayHi()
}
2.类型检查和转换
要测试某个对象是否属于某个给定的类,可以用isInstanceOf方法。用asInstanceOf方法将引用转换为子类的引用。classOf获取对象名。
classOf[String]就如同Java的String.class。
obj.isInstanceOf[T]就如同Java的 obj instanceofT 判断obj是不是T类型。
obj.asInstanceOf[T] 就如同Java的(T)obj 将obj强转成T类型。
println(classOf[String]) // 输出
val s = "king"
println(s.getClass.getName) //使用反射机制
//isInstanceOf asInstanceOf
var p1 = new Person
var emp = new Emp
//将子类引用给父类(向上转型,自动)
p1 = emp
//将父类的引用重新转成子类引用(多态),即向下转型
var emp2 = p1.asInstanceOf[Emp]
emp2.sayHello()
3.超类的构造
类有一个主构造器和任意数量的辅助构造器,而每个辅助构造器都必须先调用主构造器(也可以是间接调用)。只有主构造器可以调用父类的构造器,辅助构造器不能直接调用父类的构造器,在Scala的构造器中,不能调用super(params)。
//父类Person
class Person(pName: String) {
var name = pName
println("Person...")
def this() {
this("默认的名字")
println("默认的名字")
}
}
//子类Emp继承Person
class Emp(eName: String, eAge: Int) extends Person(eName) {
println("Emp ....")
//辅助构造器
def this(name: String) {
this(name, 100) // 必须调用主构造器
this.name = name
println("Emp 辅助构造器~")
}
def showInfo(): Unit = {
println("雇员的名字 ", name)
}
4.覆写字段
子类改写父类的字段,称之为覆写/重写字段。覆写字段需要使用override修饰 .在Java中只有方法的重写,没有属性/字段的重写,准确的讲,是隐藏字段代替了重写。
object ScalaFiledOverride {
def main(args: Array[String]): Unit = {
val obj1: AAA = new AAA
val obj2: BBB = new BBB
//obj1.age => obj1.age() //动态绑定机制
//obj2.age => obj2.age()
println("obj1.age=" + obj1.age + "\t obj2.age=" + obj2.age)
}
}
class AAA {
val age: Int = 10 // 会生成 public age()
}
class BBB extends AAA {
override val age: Int = 20 // 会生成 public age()
}
def只能重写另一个def(即:方法只能重写另一个方法)
val只能重写另一个val属性 或 重写不带参数的def
var只能重写另一个抽象的var属性
5.抽象属性
抽象属性:声明未初始化的变量就是抽象的属性,抽象属性在抽象类中。
一个属性没有初始化,那么这个属性就是抽象属性。抽象属性在编译成字节码文件时,属性并不会声明,但是会自动生成抽象方法,所以类必须声明为抽象类。如果是覆写一个父类的抽象,那么override关键字可以省略[原因:父类的抽象属性,生成的是抽象方法,因此不涉及到方法重写的概念,override可以省略]
6.抽象类
在Scala中,通过abstract关键字标记不能被实力化的类。方法不用标记abstract,只要省掉方法体即可,抽象类可以拥有抽象字段,抽象字段/属性就是没有初始值的字段。
abstract class Animal {
var name: String //抽象的字段
var age: Int // 抽象的字段
var color: String = "black" //普通属性
def cry() //抽象方法,不需要标记 abstract
}
抽象类不能被实例。
抽象类不一定要包含abstract方法。抽象类中可以有实现的方法。
一旦类包含了抽象方法或者抽象属性,则这个类必须声明为abstract。
抽象方法不能有主体,不允许使用abstract修饰(与java不同)。
如果一个类继承了抽象类,则它必须实现抽象类中所有的抽象方法和抽象属性,除非它自己也声明为abstract类。
抽象方法和抽象属性不能使用private、final来修饰,因为这些关键字都是和重写/实现相违背的。
子类重写抽象方法不需要override,写上也不会错。
7.匿名子类
object boke_demo01 {
def main(args: Array[String]): Unit = {
val monster = new Monster {
override def cry(): Unit = {
println("...:)")
}
override var name: String = _
}
monster.cry()
}
}
abstract class Monster {
var name: String
def cry()
}
————Blueicex 2020/2/17 12:06 blueice1980@126.com