類class
Scala中類的定義跟Java很相似,類是由屬和方法組成喘沿,同樣可以使用new的方式創(chuàng)建對象實例,進而調(diào)用類中定義好的方法與屬性。下面就是一個簡單的Scala類
class People {
// 屬性的定義: val/var 名稱:類型 = 值
var name:String = _ // _ 占位符 前提是一定要明確是什么數(shù)據(jù)類型
var age:Int = 3
// 私有屬性舅桩,外部不能直接調(diào)用
private var gender = "M"
// 定義方法
def playBasketball(team:String) = {
println(name + " is playing basketball of " + team)
}
def drink() = {
name + " is drinking..."
}
}
# 主方法中調(diào)用
def main(args: Array[String]): Unit = {
val people = new People // 實例化一個Class對象
people.name = "周琦" // 為對象賦值
people.age = 30
// people.gender 無法調(diào)用
println(people.name + " : " + people.age )
people.playBasketball("China")
println(people.drink())
}
}
但是Scala中類的構(gòu)造器與Java完全不一樣,主要分為主構(gòu)造器和附屬構(gòu)造器凫岖。代碼示例如下:
/**
* 主構(gòu)造器 類名(參數(shù)名:參數(shù)類型)
* 如果你想在外面調(diào)用Person的name和age必須在之前加val或者var,默認(rèn)是私有的
*/
class Person(val name:String,val age:Int){
println("進入Person主構(gòu)造器")
var job:String = _ // _ 占位符 前提是一定要明確是什么數(shù)據(jù)類型
val sex="男"
/**
* 附屬構(gòu)造器的名稱 this
* 每個附屬構(gòu)造器的第一行必須調(diào)用主構(gòu)造器或者其他的附屬構(gòu)造器
*/
def this(name:String,age:Int,job:String){
this(name,age)
this.job=job
}
println("執(zhí)行完P(guān)erson主構(gòu)造器")
}
無論你調(diào)用哪個構(gòu)造器來創(chuàng)造類實例江咳,一定會將類從頭到尾執(zhí)行一遍。同樣的子類創(chuàng)建時也會執(zhí)行父類主構(gòu)造器哥放。
/**
* override是子類重寫父類中的屬性或者方法的修飾符
* new 子類會調(diào)用父類的構(gòu)造
* 子類構(gòu)造器只能在父類主構(gòu)造器上添加屬性
*/
class Student(name:String,age:Int,val major:String) extends Person(name,age){
println("進入Student構(gòu)造器")
override val sex="女"
override def toString: String = {
this.name+"\t"+this.age+"\t"+this.job+"\t"+this.sex+"\t"+this.major
}
println("執(zhí)行完Student構(gòu)造器")
}
抽象類
/**
* 抽象類:
* 1) 類中有一個或者多個方法/屬性的定義歼指,沒有實現(xiàn)
* 2) 抽象類是不能直接new
* 3) 使用時要有完全實現(xiàn)了抽象方法/屬性的子類才行
* 4) 子類重寫父類方法或者屬性時不一定需要override
*/
object AbstractClassApp {
def main(args: Array[String]): Unit = {
val people = new People
people.speak
println(people.sum(1))
}
}
abstract class action {
def speak
val word: String
val a=1
def sum(a:Int)=a+1
}
class People extends action {
def speak: Unit = {
println(word)
}
override val word: String = "hello"
}
對象Object
- Object可以擁有屬性和方法,且默認(rèn)都是"static"類型甥雕,可以直接用object名直接調(diào)用屬性和方法踩身。
- Object里的main函數(shù)式應(yīng)用程序的入口。
伴生對象和伴生類
object ApplyApp {
def main(args: Array[String]): Unit = {
val apply = ApplyTest() //調(diào)用得是object的apply
val test = new ApplyTest
test() //調(diào)用的是class的apply
}
/**
* object是class的伴生對象
* class是object的伴生類
* 類名()=>object apply
* 對象名()=>class apply
*/
object ApplyTest{
println("進入object ApplyTest")
val name="name"
def test()={
println("test")
}
def apply(): Unit ={
println("object apply")
new ApplyTest
}
println("退出object ApplyTest")
}
class ApplyTest{
def apply(): Unit ={
println("class apply")
}
}
}
Trait
Scala的Trait相當(dāng)于Java里的Interface社露,但Trait不僅可以定義函數(shù)挟阻,還可以有函數(shù)體實現(xiàn)。實現(xiàn)關(guān)鍵詞是extends峭弟,實現(xiàn)多個Trait用with附鸽。當(dāng)extends的多個Trait里有相同函數(shù)時,子類必須重寫該函數(shù)瞒瘸。
- 父trait里無函數(shù)體的函數(shù)坷备,子類必須override
- 重寫父類里有函數(shù)體的函數(shù),必須有關(guān)鍵詞override
- trait里的變量情臭,都是val類型
- 在trait里定義的的變量省撑,必須是val類型赌蔑,如果變量沒初始化,子類必須override
- 建議看看Spark源碼的Logging
case class/case object
- case class必須要有參數(shù)列表竟秫,case object必須不能加參數(shù)列表
- class 和 case class的區(qū)別:
case class重寫了toString娃惯,equals,hashCode
case class默認(rèn)實現(xiàn)了序列化
case class不用new
object CaseClassApp {
def main(args: Array[String]): Unit = {
println(Dog("旺財").name)
}
}
case class Dog(name:String)