scala基礎-class、object的一些體會
阿新 • • 發佈:2019-01-31
1、定義成員private與預設public
1.1成員定義private的時候也會預設定義private的get和set方法,因為是私有的所以不可訪問。
這個時候就需要自己定義set、get方法來訪問name。
1.2如果將成員定義為public,此時會預設定義public的get和set的方法,但是成員為私有的。
我們訪問name其實是訪問name的get、set方法。
object ProTest1 {
def main(args: Array[String]): Unit = {
val scala = new Hiscala
// 以下兩種呼叫方式在沒有引數的時候是等價的
scala.sayName()
scala.sayName
// println(scala.name) private是私有的,不可直接訪問,但是可通過getName方法進行訪問
println(scala.getName)
}
}
class Hiscala{
private var name = "scala"
def sayName(){ println("Hi, " + name) }
def getName = name
}
輸出:
Hi, scala
Hi, scala
scala
2、get方法的覆寫
object ProTest1 {
def main(args: Array[String]): Unit = {
val scala = new Person
println(scala.name)
scala.name = "Spark"
println(scala.name)
scala.update("Hadoop")
println(scala.name)
}
}
class Person{
private var myName = "Kylin"
def name = this.myName
// name_=實際為name的set方法的覆寫,也就是set方法,所以可以直接呼叫name = newName
def name_=(newName : String){
this.myName = newName
println("Hi, " + myName)
}
// 同時可以自定義函式實現set方法
def update(newName : String){
myName = newName
println("Hi, " + myName + ". See you again!")
}
}
輸出:
Kylin
Hi, Spark
Spark
Hi, Hadoop. See you again!
Hadoop
3、private[this]的使用
private[this]不允許其他物件訪問,物件私有,只能這個物件訪問,這個物件的類中的方法也不可以訪問這個成員。其他物件中的方法也不可訪問。
object ProTest1 {
def main(args: Array[String]): Unit = {
val personA = new Person()
val personB = new Person
personA.getName()
personA.getName(personB)
// 實現getName的過載
}
}
class Person{
var nameA = "AAA"
private var nameB = "BBB"
private[this] var nameC = "CCC"
def getName()={
println(nameA + "\t" +nameB + "\t" +nameC)
}
// 呼叫公開的nameA與私有的nameB都是可行的
def getName(p:Person){
println(nameA + "\t" +nameB)
}
// 使用nameC的時候報錯value nameC is not a member of com.yanch.cn.Person
/*
def getNameC(c:Person){
println("It's " + c.nameC)
}*/
}
輸出:
AAA BBB CCC
AAA BBB
4、構造器的過載
object ProTest1 {
def main(args: Array[String]): Unit = {
// 呼叫預設構造器
val scala = new Person
println("-" * 20)
// 呼叫 預設構造器
val scala2 = new Person()
println("-" * 20)
// 呼叫 this(newName : String)構造器
val scala3 = new Person("Spark")
println("-" * 20)
// 呼叫 this(newName : String, age : Int)構造器
val scala4 = new Person("Spark", 30)
}
}
class Person{
println("aaaa")
private var myName = "Kylin"
private var age = 10
def this(newName : String){
this()
myName = newName
println("This is a newname!" + myName)
}
def this(newName : String, age : Int){
this(newName)
this.age = age
println("This is a new age!" + age)
}
}
輸出:
aaaa
--------------------
aaaa
--------------------
aaaa
This is a newname!Spark
--------------------
aaaa
This is a newname!Spark
This is a new age!30
5、伴生物件object
5.1 object 成員函式為靜態的,可以直接呼叫;
5.2 object 有自帶的預設構造器,而且只在呼叫object成員的時候第一次執行,後面不執行;
5.3 同文件中同名的class類即為其伴生類,object為class的伴生物件;伴生類與伴生物件必須在同一個檔案之中;
5.4 伴生物件中有apply方法,當前類的伴生物件的工廠方法;
5.5 抽象類依舊可以通過伴生物件的工廠方法來構造例項化。
object ProTest2 {
def main(args: Array[String]): Unit = {
// 使用new構造Person2類的例項
val p1 = new Person2
println(p1.getAge)
println("-" * 20)
// 使用伴生物件構造例項
val p2 = Person2
println(p2.getAge2)
println("-" * 20)
// 使用伴生物件的apply犯法構造類Person2的例項
val p3 = Person2()
println(p3.getAge)
println("-" * 20)
// object 有自帶的預設構造器,而且只在呼叫object成員的時候第一次執行,後面不執行
// object 成員函式為靜態的,可以直接呼叫
println(Person2.getAge2)
}
}
class Person2{
println("It's a class !")
private var age = 10
def getAge = age
}
object Person2{
println("It's a object !")
private var age2 = 1
def getAge2 = age2
def apply()={
println("It's a apply method !")
new Person2
}
}
輸出:
It's a class !
10
--------------------
It's a object !
1
--------------------
It's a apply method !
It's a class !
10
--------------------
1
6、抽象類
抽象類加final,則無法被繼承(方法也是如此)
override 覆寫父類的方法(統一,抽閒方法不寫不影響功能),覆寫父類非抽象方法就必須加override。
object ProTest2 {
def main(args: Array[String]): Unit = {
val c1 = new Cat
c1.eat
// 使用apply工廠方法
val c2 = Cat()
c2.eat
}
}
abstract class Animal{
var color : String
var action : String
def eat
}
class Cat extends Animal{
override var color = "Black"
override var action = "Creep"
override def eat{
println("Fish !")
}
}
object Cat{
def apply()={
println("It's a cat !")
new Cat
}
}
輸出:
Fish !
It's a cat !
Fish !