Scala面向對象

定義類

//不用修飾符
class HelloWorld{
    //定義一個私有的field 
    private var name = "CZM"
    def fun(){
        //這是一個帶參數的方法
    }

    def getName = name
    //定義一個不帶參數的方法

建立對象

val helloWorld = new HelloWorld     //括號無關緊要

調用方法

//能夠不寫*()*
helloWorld.fun()

//不能寫*()*
helloWorld.getName

getter和setter方法

  • 定義不帶private的var field Scala生成面向JVM的類時,會定義成private的字段,並提供Public的getter和setter (也就是說,你在用對象調用這個值的時候,底層轉換爲使用pubic的getter/setter方法訪問)
  • 定義帶private的field,則生成的getter和setter方法也是private的,外部不能調用,只能經過暴露的方法獲得
  • 定義成val field時,只會生成getter方法
  • 若是不但願生成getter和setter方法,則將field聲明成privete[this]
//自動生成的getter和setter方法,經過 val var private private[this]
var name = "CZM"
/*自動生成以下代碼
//getter
def name = name

//setter
def name_ = (new_name:String)
*/

//手動getter和setter
private var name= "CZM"
def name = "Your name is "+name     //錯誤,由於這樣至關於兩次定義了name

class HelloWorld {
  private var old_name= "CZM"
    def name = "Your name is "+old_name     //正確:old_name 做爲類中的私有feild,僅僅提供私有的getter和setter方法,而name做爲一個提供了public的getter和setter方法的feild ==> var name並重寫了public的getter和setter
    def name_=(new_name: String) {      //須要注意的是這裏的語法規則,**=號先後不容許有空格**
    old_name = new_name
    print("Your new name is " + old_name)
  }
}

//調用getter和setter
var helloWorld = new HelloWorld()
helloWorld.name //geter 
helloWorld.name_= "asd" //正兒八經setter
helloWorld.name = "asd" //新型setter,將name做爲返回,買一送一

privete[this]的使用

class Student{
    private var myAge = 0
    //private[this] var myAge = 0 //調用getter方法會報錯,即便定義了getter和setter方法

    def age = myAge
    def age_=(newValue:Int){
        if (newValue<0){println("illegal gar!!")}
        else{myAge = newValue}
    }
    def older(s:Student){
        myAge > s.myAge 
    }
}

懷舊黨專用,使用類JAVA的getter和setter方法

@BeanProperty var age = 0
@BeanProperty var age:Int = _   //使用佔位符須要聲明類型

//同時擁有兩種調用方式
s1.getAge
s1.age

構造函數constructor

主constructor

  • 主構造函數就是與類名在一塊兒的構造函數,關鍵問題是,當主構造函數定義了以後,就不能調用無參構造函數了,也就是說,主構造函數定義了最少參數的構造函數,之後就只有更多參數的了
  • 主constructor中定義的參數,若是被使用到,則會被聲明成privat[this] var name
  • 若是類中沒有使用到這個參數,則不會被聲明,並不會有這個feild
//固然,能夠設置默認參數 
class Student(name:String,age:Int){}

輔助constructor

class Student(){
    private var name = ""
    private var age = 0

    def this(name:String){
        this()      //若是不相互調用,必須調用**主構造函數**,且要在**首行 == JAVA**
        this.name = name
    }

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

內部類

與JAVA不一樣的是,Scala中的外部類的對象的內部類都是不一樣的類java

import scala.collection.mutable.ArrayBuffer

class Class {

  class Student(name: String) {}

  val students = new ArrayBuffer[Student]()

  def getStudent(name: String) = {
    new Student(name)
  }
}

val c1 = new Class
val c2 = new Class

val s1 = c1.getStudent("CZM")       //s1: c1.Student = Class$Student@1d3f8af1
val s2 = c2.getStudent("czm")       //s2: c2.Student = Class$Student@73589106

c1.students += s1   //正確
c1.students += s2   //錯誤,每個內部類都是屬於對象的,而不是獨立存在的

/*錯誤信息
Error:(21, 24) type mismatch;
found   : c2.Student
required: c1.Student
c1.students += s2
*/

object對象

因爲類中定義的feild都是屬於對象的,並無屬於類的字段,在JAVA中使用Static定義的字段做爲全部對象共用的類的字段,在scala中提供了object來存放。spring

  • object 也有constructor(不屬於方法的代碼都是靜態加載),只在第一次被調用時執行一次,不能定義帶參數的constructor
  • object一般用做單例模式(只有本身一個對象),或者做爲伴生對象存放靜態成員,靜態工具方法
  • 與class相比,object僅僅是不能定義帶參數的constructor,其餘都是同樣的,能繼承其餘方法
//定義object對象
object Person {     //不能有括號,不能定義帶參數的constructor
  private var name = ""
  println("This is constructor!")
  def getName = name
  println("This is constructor too!")
}
Person.getName

//讓object繼承抽象類
abstract class Hello {
  def syaHello(name: String): Unit
}

object HelloObject extends Hello {
  override def syaHello(name: String): Unit = {
    println("Implement from Hello, your name is " + name)
  }
}

HelloObject.syaHello("CZM")

伴生對象和伴生類

  • 在同一個.scala文件中。同名的class和object,稱object爲class的伴生對象,class稱爲object的伴生類
  • 伴生對象和伴生類之間能夠相互訪問private的feild
  • class中的一切屬於對象
  • object中的一切屬於類
class Person(name: String, age: Int) {
  def sayHello = {
    println("Hello " + name + " you are " + age + " years old, and you must have " + Person.legNum + "legs")    //須要加上Object名訪問object對象變量(即便不是私有的)
  }
}

object Person {
  private var legNum = 2    def getLegNum = legNum }

val p1 = new Person("czm", 18)
p1.sayHello

Apply方法(容許重載?)

  • apply方法中通常作什麼?建立一個對象,並返回對象
  • 爲何要Apply方法?讓建立類對象來的更簡單,直接使用 類名()便可
  • 爲何要在伴生對象中建立apply方法?由於這是一個工具方法,不該該屬於對象,應該用類名調用
class Person(name: String)

object Person {
  def apply(name: String): Person = new Person(name)
}
Person("你好")

main方法

  • 爲何要main方法?做爲函數的入口
  • 爲何要定義在object中?由於main是public static的,須要被JVM使用類名調用

方法1

//注意文件名與類名相同
object HelloWorld {
  def main(args: Array[String]) {
    if (args.length != 0) {
      println("Hello " + args(0))
    } else {
      println("Hello World!")
    }
  }
}

方法2:繼承APP Trait

繼承APP Trait,而後將須要在main中運行的代碼,直接在constructor中編寫。直接使用args接收傳入的參數黑人問號臉??:這裏的參數是來自父類APP Trait的父類DelayedInit Trait的Main方法中的args數組

  • 工做原理:APP Trait 繼承自DelayedInit Trait 編譯時會將object中的constructor中的代碼放到DelayedInit Trait的delayedInit方法中執行。DelayedInit的main方法將會調用delayedInit方法(爲了懶加載?)
object HelloWorld extends App{
    if (args.length != 0) {
      println("Hello " + args(0))
    } else {
      println("Hello World!")
    }
}

使用object實現枚舉

  • 枚舉是什麼:枚舉是一個特殊的類,就是固定的多個常量對象的集合
  • Scala沒有提供相似JAVA中的Enum這樣的枚舉特性,可使用object繼承Enumeration類,而且調用Value方法來初始化枚舉值
  • 調用時,直接使用Season(0),爲何,不會跟apply衝突嗎?繼承了Enumeration,Enumeration中的apply方法是final的,子類不容許再定義apply只能繼承Enumeration的apply(詳情親看源碼)

scala實現枚舉

object Season extends Enumeration{
  val SPRING,SUMMER,AUTUMN,WINTER = Value   //Value方法繼承於Enumeration
  //能夠自定義Value的元素
  val SPRING = Value(0,"spring")
  ...
}

//調用
//Enumeration的apply方法返回一個Value對象                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
Season(0)
res0: Season.Value = SPRING

Season("spring")

java中的枚舉

enum Weeday{
    SUNDAY,MONDAY.TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
}

//在底層
//建立了一個final的Weeday類繼承Enum
//實例化各個字段爲 public final static 的 Weekday 對象,存在數組$VALUES中
//定義了一個values方法,用於返回數組      //Weekday.values()
//定義了一個valueOf方法,用於返回           //Weekday.valueof("SUNDAY")
相關文章
相關標籤/搜索