1. 程式人生 > >Scala 學習(4)之「類——基本概念2」

Scala 學習(4)之「類——基本概念2」

目錄

  • 內部類
  • extends
  • override和super
  • override field
  • isInstanceOf和asInstanceOf
  • getClass和classOf

內部類

import scala.collection.mutable.ArrayBuffer
class Class {
    class Student(val name: String) {}      //此處為內部類
    val students = new ArrayBuffer[Student]
    def getStudent(name: String) = {
        new Student(name)
    }
}

val c1 = new Class
val s1 = c1.getStudent("0mifang")
c1.students += s1

val c2 = new Class
val s2 = c2.getStudent("0mifang1")
c1.students += s2       //錯誤的演示

extends

  • 繼承就代表子類可以從父類繼承父類的 field 和 method ;然後子類可以在自己內部放入父類所沒有,子類特有的 field 和 method,使用繼承可以有效複用程式碼。
  • 子類可以覆蓋父類的 field 和 method,但是如果父類用 final 修飾,field 和 method 用 final 修飾,則該類是無法被繼承的,field 和 method 是無法被覆蓋的。
class Person {
    private var name = "0mifang"
    def getName = name
}
class Student extends Person {
    private var score = "A"
    def getScore = score
}

var student = new Student
student.getName

override和super

  • 如果子類要覆蓋一個父類中的非抽象方法,則必須使用 override 關鍵字 override
  • 關鍵字可以幫助我們儘早地發現程式碼裡的錯誤,比如:override 修飾的父類方法的方法名我們拼寫錯了;比如要覆蓋的父類方法的引數我們寫錯了;等等
  • 此外,在子類覆蓋父類方法之後,如果我們在子類中就是要呼叫父類的被覆蓋的方法,那就可以使用 super 關鍵字,顯式地指定要呼叫父類的方法
class Person {
    private var name = "0mifang"
    def getName = name

}
class Student extends Person {
    private var score = "A"
    def getScore = score

    override def getName = "Hi, I'm " + super.getName
}

var student = new Student
student.getName     // 可以發現,student 類繼承了 Person 類的 getName 方法

override field

子類可以覆蓋父類的 val field,而且子類的 val field 還可以覆蓋父類的 val field 的 getter 方法,只要在子類中使用 override 關鍵字即可

class Person {
    val name: String = "Person"
    def age: Int = 0
}

class Student extends Person {
    override val name: String = "0mifang"
    override val age: Int = 18
}

val person = new Person
val student = new Student
person.name
person.age
student.name
student.age

isInstanceOf和asInstanceOf

如果我們建立了子類的物件,但是又將其賦予了父類型別的變數。則在後續的程式中,我們又需要將父類型別的變數轉換為子類型別的變數,應該如何做?
首先,需要使用 isInstanceOf 判斷物件是否是指定類的物件,如果是的話,則可以使用 asInstanceOf 將物件轉換為指定型別。

  • 如果物件是 null,則 isInstanceOf 一定返回 false,asInstanceOf 一定返回null;
  • 如果沒有用 isInstanceOf 先判斷物件是否為指定類的例項,就直接用 asInstanceOf 轉換,則可能會丟擲異常。
class Person
class Student extends Person
val p: Person =  new Student
var s: Student = null
// 如果 p 是 Student 類,則讓 s 指向 p 轉換為 Student 的物件
if (p.isInstanceOf[Student]) s = p.asInstanceOf[Student]

getClass和classOf

  • isInstanceOf 只能判斷出物件是否是指定類以及其子類的物件,而不能精確判斷出,物件就是指定類的物件;
  • 物件.getClass 可以精確獲取物件的類,classOf[類] 可以精確獲取類,然後使用 == 操作符即可判斷。
class Person
class Student extends Person

val p: Person = new Student
p.isInstanceOf[Person]          //true
p.getClass == classOf[Person]   //false
p.getClass == classOf[Student]  //true





歡迎關注,本號將持續分享本人在程式設計路上的各種見