Scala繼承

override重寫

  • 爲何要用override關鍵字?由於這樣更清楚,不容易出錯,好比打錯字了,就沒覆蓋成功,可是不會報錯
  • override能夠覆蓋feild和method
class Person{
    private val name = "CZM"
    def getName = name
}

class Student extends Person{
    private val score = "A"
    def getScore = score
    override def getName = "My name is "+super.getName      //重寫須要使用關鍵字override聲明。若是父類定義爲final則不可重寫
}

val s1 = new Student
s1.getScore
s1.getName

isInstanceOf和asInstanceOf:多態判斷

  • 在多態的轉換中,會把子類對象賦值給父類變量,若是遇到須要把原本是子類的對象變回子類怎麼實現?
  • isInstanceOf用於判斷是不是指定類的對象
  • asInstanceOf用於將對象轉換成指定類型
//接上文代碼

//舊API,這個並不能精準判斷
val p1:Person = new Student
if (p1.isInstanceOf[Student]){
  val s1:Student = p1.asInstanceOf[Student]     //p1的本質是沒有改變的,返回一個clone的對象
  s1.getScore //若是不轉換,這個學生就失去了這個方法
}

//新API,非精準判斷
p1 match {
  case _: Student =>
    p1.asInstanceOf[Student]
    p1
  case _ =>
}

getClass和classOf:精準判斷

val p1: Person = new Student
val s1 = new Student
p1.getClass == classOf[Student]     //false
p1.getClass == classOf[Person]      //true

protected關鍵字

除了private以外,scala還提供和了protect關鍵字,子類訪問權限java

  • private[this]:出了本身的{ }就不認可了,就好比說一我的有病,只有本身知道,在外人看來是不存在的,兒子也不知道
  • protected[this]:出了本身和兒子的{ }就不認可了,就好比說一我的有病,只有本身和兒子知道,在外人看來是不存在的,兒子不會告訴別人的兒子
class Person() {
  protected[this] val name = "CZM"    def getName = name }

class Student extends Person {
  private val score = "A"    def getScore = score    def makeFriend(s: Student): Unit = {
    println("My name is " + name + " , I'm " + s.name + " is friend!")      //在本身家能夠調用name,沒法調用s.name至關於本身兒子去了別人家
  }
}

val s1 = new Student
val s2 = new Student
s1.makeFriend(s2)

調用父類constructor

  • 爲何調用父類構造函數這麼奇葩? 由於子類constructor第一行必須調用主constructor或者其餘輔助constructor
  • 爲何不用super(...)? 由於沒有
//父類,定義了兩個constructor
class Person(val name: String) {
  var age = 10    def getName = name

  def this(name: String, age: Int) {
    this(name)
    this.age = age
  }
}

//子類    定義本身的constructor(name:傳值,age:重寫父類中的age字段,score:定義本身的變量score) Person()這裏就決定了調用哪個constructor
class Student(name: String, override val age: Int, val score: Double) extends Person(name) {

匿名內部類

  • 匿名內部類:定義一個沒有名稱的某個類(接口)的子類,並立刻實例化new
  • 匿名內部類自己沒有構造器,可是會調用父類構造器
  • 匿名內部類必須繼承或實現一個接口,但最多隻能一個父類或實現一個接口(JAVA == scala)

JAVA中的匿名內部類

new 父類構造器( ) 或  接口( )
{
    //todo
}

scala中的匿名內部類,跟JAVA沒有一點區別

class Person(val name: String) {
  def sayHello = println("Person class " + name)
}

val p1 = new Person("CZM")    //p1是一個Person類的對象 
val p2 = new Person("leo") {  //p2是一個Person類的匿名子類的對象
  override def sayHello = println("new sun class " + name)
}

p1.sayHello
p2.sayHello

abstract抽象

  • 子類覆蓋抽象類的抽象方法能夠不須要override,IDEA推薦仍是使用override
  • 抽象類中容許有非抽象方法
  • 沒有implement關鍵字,依然使用extends
  • 能夠抽象field(須要在抽象類中),編譯在編譯抽象類時,生成了getter和setter方法,可是父類中沒有這個field
//抽象類和抽象方法
abstract class Person {
  def sayHello():Any
}

class student extends Person{
  override def sayHello() = ??? }

//抽象類和抽象field
abstract class Person {
  abstract val name:String }
相關文章
相關標籤/搜索