Scala(三):類

奮鬥的only發表於2018-12-16
類:Class
1.簡單類和無參方法
2.帶getter和setter屬性
3.只帶getter屬性
4.物件私有欄位
5.Bean屬性
6.輔助構造器
7.主構造器
8.巢狀類
1.簡單類和無參方法
Scala中的簡單類和Java中很相似
class ClassOps{
  private var value = 0 //你必須初始化欄位

  def  increment(){value += 1} //方法預設是公有的

  def current() = value

}
/*
   *在Scala中類並不宣告為public,,Scala原始檔包括多個類,所以這些類都具有公共可見性
   * 使用該類需要做的就是構造物件並按照通常的方式呼叫方法
   */

object Class {
  def main(args: Array[String]): Unit = {
    val myCounter = new ClassOps
    myCounter.increment()
    println(myCounter.current)//此處呼叫無參構造時,()可加也可不加


  }
}

2.帶getter和setter屬性

/**
 *public class Person{
 *     public Int age  //Java中並不推薦這樣使用
 *     private String name
 *     public String getName(){return name;}
 *     public void setName(String name){this.name=name}
 *}
 * 像這樣一對getter/setter通常叫做屬性(property)
 * Scala中對每個欄位都給生成getter/setter方法,不過我們可以控制這個過程
 *    如果欄位私有,則getter/setter也是私有的
 *    如果欄位被val修飾,那麼只有getter生成
 *    如果你不需要getter/setter,那麼可以將欄位宣告為private[this]
 */
//Scala中每個欄位都提供getter和setter方法
class Person{
 // var age = 0
  /*
   *Scala生成面向JVM的類,其中有一個私有欄位age欄位和相應的getter/setter方法,
   *在Scala中此處,getter和setter分別為age和age_=
   */
  //重寫getter和setter
  private var privateAge = 0 //變成私有並改名
  def age = privateAge       //getter

  def age_(newValue : Int ){ //setter方法
    if(newValue > privateAge) privateAge = newValue
  }
}
object Person{
  def main(args: Array[String]): Unit = {
    val p = new Person
    println(p.age)

    p.age_(40)
    println(p.age)   //列印結果:40
    p.age_(30)
    println(p.age)   //列印結果:40
  }
}

3.物件私有欄位

 在Scala中,方法可以訪問該類的所有物件的私有欄位

class atm{
  private var momey = 0
  def drawMoney(){momey += 1}
  def spendMoney(other : atm) = momey < other.momey
  //之所以訪問other.money是合法的是因為other也是atm物件
  //Scala允許我們定義更加嚴格的訪問限制,通過private[this]
  private[this] var foods = null //在這物件.value行不通
  //類私有欄位,Scala會生成私有getter/setter,但是物件私有的欄位不會生成
  //private[類名],這樣的只有指定類才能訪問

}

4.Bean屬性

  當你將Scala欄位標註為@BeanProperty時,會自動生成四個方法

import scala.reflect.BeanProperty
class superMan{

  @BeanProperty var name : String  = _

}
/*
 *將會生成如下四個方法:
 * name :String
 * name_=(newValue:String):Unit
 * getName():String
 * setName(newValue:String):Unit
 */

5.輔助構造器

 Scala中有主構造器和輔助構造器
輔助構造器和Java中的構造器很相似,只有兩處不同
1.輔助構造器名稱是this,Java中構造器名和類名相同
2.每一個輔助構造器必須以一個先前已定義的其他輔助構造器或主構造器的呼叫開始
class SuperWoman{
    private var name = ""
    private var age = 0

    def this(name:String ) {
      this()    //呼叫主構造器
      this.name=name
    }
    def this(name :String ,age :Int){
      this(name)         //呼叫前一個輔助構造器
      this.age=age
    }
     //一個類中沒有顯式的定義主構造器,那麼會預設的定義一個無參的主構造器
  
}

object superWoman {
          //三種方式構建物件
  val s1 = new SuperWoman
  val s2 = new SuperWoman("John")
  val s3 = new SuperWoman("John",30)
}

6.主構造器

在Scala中,每個類都有主構造器,主構造器並不以this方法定義,而是與類定義交織在一起
主構造器的引數被編譯成欄位,其值被初始化成構造時傳入的引數
在Scala中,類也接受引數,和方法一樣
class SuperBoy(val name:String,val age:Int){
  //(...)中的內容就是主構造器的引數
  println("this is construct")

  override def toString = s"SuperBoy($name, $age)"
}
//構造引數也可以是普通的方法引數,不帶val或者var,這樣的引數如何處理取決於它們在類中如何被使用
//如果不帶val或者var的引數至少被一個方法使用,它將被升級為欄位
class SuperGirl(name:String,age:Int){
  def description=name + "is" + age + "years old"
}
//上述程式碼宣告並初始化了不可變欄位name和age,而這兩個欄位都是物件私有的,類似於private[this]
//當你把主構造器的引數看做是類引數時,不帶val或var的引數就變得易於理解了,這樣的引數的作用域覆蓋整個類,因此你可以在方法中使用,同時
//你這樣做了,編譯器自動幫你將它儲存成欄位
//如果你想把主構造器變為私有,如下
class OldMan private(val name:String,val age:Int){}//這樣只能通過輔助構造器來建立物件

7.巢狀類

 函式中定義函式,類中定義類
import scala.collection.mutable.ArrayBuffer 
class NetWork{
   class Member(val name:String){
     val contacts = new ArrayBuffer[Member]()
   }
  private val Members=new ArrayBuffer[Member]()

  def join(name:String)={
        val m =new Member(name)
        Members += m
        m
  }
}
object NetWork{
  def main(args: Array[String]): Unit = {
    //如有如下兩個網路
    val chatter = new NetWork
    val myFace= new NetWork
    //在兩個網路中新增成員
    val fred=chatter.join("fred")
    val wilma=chatter.join("wilma")
    fred.contacts += wilma
    val barney = myFace.join("barney")
    //fred.contacts += barney 不允許這樣做
    /*
     *如果你不希望是這個效果,兩種方式解決
     *   1.可以將Member類移動到NetWork的伴生物件中
     *   2.使用型別投影:NetWork#Member
     *    eg :
     *        class NetWork{
     *           class Member(val name:String){
     *             val contacts = new ArrayBuffer[NetWork#Member]()
     *            }
     *           }
     */
      //在內嵌類中,可以通過外部類.this的方式來訪問內部類的this引用,和Java一樣
  }
}

 

提示:有不妥的地方希望大家能夠批評指正,一起學習,一起進步

相關文章