Scala 面向对象(六):面向对象的特征二:继承 (一)

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可以是任何类。

 

posted @ 2020-07-07 18:52  秋华  阅读(317)  评论(0编辑  收藏  举报