继承的概念
Scala中继承类的方式和Java一样,也是使用extends关键字:
1 2 3
| class Employee extends Person{ var salary=1000 }
|
和Java一样,可在定义中给出子类需要而父类没有的字段和方法,或者重写父类的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package lagou.cn.part05
class Person(name: String, age: Int){ println("这是父类Person!") }
class Student(name: String, age: Int, var stuNo: String) extends Person(name, age){ println("这是子类Student!") }
object ExtendsDemo { def main(args: Array[String]): Unit = { val student = new Student("jacky", 30, "1001") } }
|
构造器执行顺序
Scala在继承的时候构造器的执行顺序:首先执行父类的主构造器,其次执行子类自身的主构造器。
类有一个主构造器和任意数量的辅助构造器,而每个辅助构造器都必须以对先前定义的辅助构造器或主构造器的调用开始。
子类的辅助构造器最终都会调用主构造器。只有主构造器可以调用父类的构造器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Person(name:String,age:Int){ println("这是父类Person") }
class Student(name:String,age:Int,studentNo:String) extends Person(name,age){ println("这是子类Student") }
object Demo{ def main(args: Array[String]): Unit = { val student=new Student("john",18,"1024") } }
|
override方法重写
方法重写指的是当子类继承父类的时候,从父类继承过来的方法不能满足子类的需要,子类希望有自己的实现,这时需要对父类的方法进行重写,方法重写是实现多态的关键。
Scala中的方法重写同Java一样,也是利用override关键字标识重写父类的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package lagou.cn.part05
class Programmer(name: String, age: Int) { def coding(): Unit = { println("我在写代码。。。") } }
class ScalaProgrammer(name: String, age: Int, workNo: String) extends Programmer(name, age) { override def coding(): Unit = { super.coding() println("我在写Scala代码。。。") } }
object OverrideDemo { def main(args: Array[String]): Unit = { val scalaProgrammer = new ScalaProgrammer("jacky", 30, "10010") scalaProgrammer.coding() } }
|
需要强调一点:如果父类是抽象类,则override关键字可以不加。如果继承的父类是抽象类(假设抽象类为AbstractClass,子类为SubClass),在SubClass类中,AbstractClass对应的抽象方法如果没有实现的话,那SubClass也必须定义为抽象类,否则的话必须要有方法的实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| abstract class Person(name:String,age:Int){ def walk():Unit }
class Student(name:String,age:Int,var studentNo:String) extends Person(name,age) { def walk():Unit={ println("walk like a elegant swan") } }
object Demo{ def main(args: Array[String]): Unit = { val stu=new Student("john",18,"1024") stu.walk() } }
|
类型检查与转换
要测试某个对象是否属于某个给定的类,可以用isInstanceOf方法。如果测试成功,可以用asInstanceOf方法进行类型转换
1 2 3 4
| if(p.isInstanceOf[Employee]){ val s = p.asInstanceOf[Employee] }
|
如果p指向的是Employee类及其子类的对象,则p.isInstanceOf[Employee]将会成功。
如果p是null,则p.isInstanceOf[Employee]将返回false,且p.asInstanceOf[Employee]将返回null。
如果p不是一个Employee,则p.asInstanceOf[Employee]将抛出异常。
如果想要测试p指向的是一个Employee对象但又不是其子类,可以用:
1
| if(p.getClass == classOf[Employee])
|
classOf方法定义在scala.Preder对象中,因此会被自动引入。
不过,与类型检查和转换相比,模式匹配通常是更好的选择。
1 2 3 4 5 6 7
| p match{ case s: Employee => ...
case _ => .... }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package lagou.cn.part05
class Person2
class Student2 extends Person2
object InstanceDemo { def main(args: Array[String]): Unit = { val p: Person2 = new Student2 var s: Student2 = null
println(s.isInstanceOf[Student2])
if (p.isInstanceOf[Student2]) { s = p.asInstanceOf[Student2] } println(s.isInstanceOf[Student2])
println(p.getClass == classOf[Person2]) println(p.getClass == classOf[Student2])
println("=====================================") p match { case s: Student2 => println("它是Student2类型的对象") case _ => println("它啥也不是!") } } }
|
结果:
1 2 3 4 5 6
| false true false true ===================================== 它是Student2类型的对象
|