1 Scala继承的基本语法
class 子类名 extends 父类名 { 类体 }
class Person { var name : String = _ var age : Int = _ def showInfo(): Unit = { println("学生信息如下:") println("名字:" + this.name) } } class Student extends Person { def studying(): Unit = { println(this.name + "学习 scala中....") } }
Scala继承给编程带来的便利
1)代码的复用性提高了
2)代码的扩展性和维护性提高了
scala子类继承了什么,怎么继承了?
子类继承了所有的属性,只是私有的属性不能直接访问,需要通过公共的方法去访问
object Extends02 { def main(args: Array[String]): Unit = { val sub = new Sub() sub.sayOk() }} class Base { var n1: Int = 1 protected var n2: Int = 2 private var n3: Int = 3 def test100(): Unit = { println("base 100") } protected def test200(): Unit = { println("base 200") } private def test300(): Unit = { println("base 300") } } class Sub extends Base { def sayOk(): Unit = { this.n1 = 20 this.n2 = 40 println("范围" + this.n1 + this.n2) }}
2 重写方法
说明: scala明确规定,重写一个非抽象方法需要用override修饰符,调用超类的方法使用super关键字
class Person { var name : String = "tom" def printName() { println("Person printName() " + name) } }
class Emp extends Person { //这里需要显式的使用override override def printName() { println("Emp printName() " + name) super.printName() } }
3 Scala中类型检查和转换
要测试某个对象是否属于某个给定的类,可以用isInstanceOf方法。用asInstanceOf方法将引用转换为子类的引用。classOf获取对象的类名。
1) classOf[String]就如同Java的 String.class 。
2) obj.isInstanceOf[T]就如同Java的obj instanceof T 判断obj是不是T类型。
3) obj.asInstanceOf[T]就如同Java的(T)obj 将obj强转成T类型。
类型检查和转换的最大价值在于:可以判断传入对象的类型,然后转成对应的子类对象,进行相关操作,这里也体现出多态的特点。
4 Scala中超类的构造
Scala超类的构造说明
1) 类有一个主构器和任意数量的辅助构造器,而每个辅助构造器都必须先调用主构造器(也可以是间接调用.),这点在前面我们说过了。
class Person { var name = "zhangsan" println("Person...")} class Emp extends Person { println("Emp ....") def this(name : String) { this // 必须调用主构造器 this.name = name println("Emp 辅助构造器~") }}
2) 只有主构造器可以调用父类的构造器。辅助构造器不能直接调用父类的构造器。在Scala的构造器中,你不能调用super(params)
class Person(name: String) { //父类的构造器 } class Emp (name: String) extends Person(name) {// 将子类参数传递给父类构造器,这种写法√ // super(name) (×) 没有这种语法 def this() { super("abc") // (×)不能在辅助构造器中调用父类的构造器 } }
5 覆写字段
基本介绍
在Scala中,子类改写父类的字段,我们称为覆写/重写字段。覆写字段需使用 override修饰。
Scala覆写字段快速入门
覆写字段的注意事项和细节
1) def只能重写另一个def(即:方法只能重写另一个方法)
2) val只能重写另一个val 属性 或 重写不带参数的def
3) var只能重写另一个抽象的var属性
抽象属性:声明未初始化的变量就是抽象的属性,抽象属性在抽象类
var重写抽象的var属性小结
1) 一个属性没有初始化,那么这个属性就是抽象属性
2) 抽象属性在编译成字节码文件时,属性并不会声明,但是会自动生成抽象方法,所以类必须声明为抽象类
3) 如果是覆写一个父类的抽象属性,那么override 关键字可省略 [原因:父类的抽象属性,生成的是抽象方法,因此就不涉及到方法重写的概念,因此override可省略]
6 抽象类
在Scala中,通过abstract关键字标记不能被实例化的类。方法不用标记abstract,只要省掉方法体即可。抽象类可以拥有抽象字段,抽象字段/属性就是没有初始值的字段
快速入门案例
抽象类基本语法
说明:抽象类的价值更多是在于设计,是设计者设计好后,让子类继承并实现抽象类(即:实现抽象类的抽象方法)
Scala抽象类使用的注意事项和细节讨论
1)抽象类不能被实例
2)抽象类不一定要包含abstract方法。
3)也就是说,抽象类可以没有abstract方法 一旦类包含了抽象方法或者抽象属性,则这个类必须声明为abstract
4)抽象方法不能有主体,不允许使用abstract修饰。
5) 如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法和抽象属性,除非它自己也声明为abstract类。
6)抽象方法和抽象属性不能使用private、final 来修饰,因为这些关键字都是和重写/实现相违背的。
7) 抽象类中可以有实现的方法.
8) 子类重写抽象方法不需要override,写上也不会错.
7 匿名子类
和Java一样,可以通过包含带有定义或重写的代码块的方式创建一个匿名的子类.
8 继承层级
subtype : 子类型
implicit Conversion 隐式转换
class hierarchy : 类层次
继承层级图小结
1) 在scala中,所有其他类都是AnyRef的子类,类似Java的Object。
2)AnyVal和AnyRef都扩展自Any类。Any类是根节点
3)Any中定义了isInstanceOf、asInstanceOf方法,以及哈希方法等。
4)Null类型的唯一实例就是null对象。可以将null赋值给任何引用,但不能赋值给值类型的变量
5)Nothing类型没有实例。它对于泛型结构是有用处的,举例:空列表Nil的类型是List[Nothing],它是List[T]的子类型,T可以是任何类。