Scala 學習(5)之「類——基本概念3」

使用模式匹配進行類型判斷

  • 在實際開發中,好比 spark 的源碼中,大量的地方都是使用了模式匹配的方式來進行類型的判斷,這種方式更加地簡潔明瞭,並且代碼得可維護性和可擴展性也很是的高
  • 使用模式匹配,功能性上來講,與 isInstanceOf 同樣,也是判斷主要是該類以及該類的子類的對象便可,不是精準判斷的
class Person
class Student extends Person
val p: Person = new Student

p match {		//模式匹配
	case per: Person => println("it's Person's object")
	case _  => println("unknown type")
}

// 運行後將會出現 「it's Person's object」 的字樣

protected

  • 跟 Java 同樣,Scala 中一樣可使用 protected 關鍵字來修飾 field 和 method,這樣在子類中就不須要 super 關鍵字,直接就能夠訪問父類的 field 和 method
  • 還可使用 protected[this],則只能在當前子類對象中訪問父類的 field 和 method,沒法經過其餘子類對象訪問父類的 field 和 method
class Person {
	protected var name: String = "0mifang"
	protected[this] var hobby: String = "game"
} 
class Student extends Person {
	def sayHello = println("Hello, " + name)
	
	//沒法訪問到 hobby 變量,由於被 protected[this] 所保護
	def makeFriends(s: Student) {
		println("my hobby is " + hobby + ", your hobby is " + s.hobby)
	}
}

調用父類的constructor

  • Scala 中,每一個類能夠有一個主 constructor 和任意多個輔助 constructor,而每一個輔助 constructor 的第一行都必須是調用其餘輔助 constructor 或者是主 constructor;所以子類的輔助 constructor 是必定不可能直接調用父類的 constructor 的
  • 只能在子類的主 constructor 中調用父類的 constructor,如下這種語法,就是經過子類的主構造函數來調用父類的構造函數
  • 注意!若是是父類中接收的參數,好比 name 和 age,子類中接收時,就不要用任何 val 或 var 來修飾了,不然會認爲是子類要覆蓋父類的 field
class Person(val name: String, val age: Int)
//在主 constructor 中調用父類的 constructor
class Student(name: String, age: Int, var score: Double) extends Person(name, age) {
	def this(name: String) {
		this(name, 0, 0)
	}
	def this(age: Int) {
		this("0mifang", age, 0)
	}
}

匿名內部類

匿名子類,也就是說,能夠定義一個類的沒有名稱的子類,並直接建立其對象,而後將對象的引用賦予一個變量。以後甚至能夠將該匿名子類的對象傳遞給其餘函數。編程

class Person(protected val name: String) {
	def sayHello = "Hello, I'm " + name
}
val p = new Person("0mifang") {	//匿名內部類
	override def sayHello = "Hi, I'm " + name
}
def greeting(p: Person { def sayHello: String }) {	//使用匿名內部類做爲參數
	println(p.sayHello)
}

抽象類

  • 若是在父類中,有某些方法沒法當即實現,而須要依賴不一樣的子類來覆蓋,重寫實現本身不一樣的方法實現。此時能夠將父類中的這些方法不給出具體的實現,只有方法簽名,這種方法就是抽象方法
  • 而一個類中若是有一個抽象方法,那麼類就必須用 abstract 來聲明爲抽象類,此時抽象類是不能夠實例化的
  • 在子類中覆蓋抽象類的抽象方法時,不須要使用 override 關鍵字
abstract class Person(val name: String) {
	def sayHello: Unit		//無具體實現
}
class Student(name: String) extends Person(name) {
	def sayHello: Unit = println("Hello, " + name)		//覆蓋並作出具體實現
}

抽象field

  • 在父類中,定義了 field,可是沒有給出初始值,則此 field 爲抽象 field
  • 抽象 field 意味着,Scala 會根據本身的規則,爲 var 或 val 類型的 field 生成對應的 getter 和 setter 方法,可是父類中是沒有該 field 的,子類必須覆蓋 field,以定義本身的具體 field,而且,覆蓋抽象 field,不須要使用 override 關鍵字
abstract class Person {
	val name: String	//無初始值
}
class Student extends Person {
	val name: String = "0mifang"	//覆蓋並給出初始值
}

歡迎關注,本號將持續分享本人在編程路上的各類見聞。ide

相關文章
相關標籤/搜索