1.類
1.1.字段的getter、setter方法
如果字段是私有的,則getter和setter方法也是私有的
如果字段是val,則只有getter方法被生成。
如果你不需要任何getter或setter,可以將字段聲明爲private[this]
重定義getter,setter方法
Class Person{
private var privateAge = 0
def age = privateAge //setter方法scala中叫做age
def age_= (newValue: Int){ //getter方法scala中叫做age_
if (newValue > privateAge) privateAge = newValue
}
}
可以用@BeanProperty註解來生成JavaBeans的getXxx/setXxx方法
1.2.構造器
構造器在類初始化的時候被調用通常被用來做一些初始化的工作。
1.2.1.主構造器和輔助構造器
1.scala主構造器執行類體中所有的語句。
2.如果主構造器參數不帶val或var,那麼會根據是否被方法使用來決定。
如果不帶val或var的參數被至少一個方法使用了,它會變爲對象私有的不可變字段,類似這樣的字段等同於private[this] val字段的效果;
如果沒有被方法使用,該參數將不被保存爲字段,它僅僅是一個可以被主構造器中的代碼訪問的普通參數。(這是一個具體實現相關的優化)
3.scala中輔助構造器和Java中的構造函數對應。
4.輔助構造器名稱是this
5.輔助構造器必須以一個已經定義的主構造器或其他輔助構造器的調用開始。
class person {
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
}
}
val p1 = new Person //主構造器
val p2 = new Person("Fred")//第一個輔助構造器
val p3 = new Person("Fred", 42) //第二個輔助構造器
1.2.2.子類的構造器
子類的輔助構造器最終都會調用子類的主構造器,只有子類的主構造器可以調用超類的主構造器。
//scala 主構造器和子類結合在一起
class Employee(name: String, age: Int, val salary: Double) extends Person(name, age)
//java主構造器名和類名相同
public class Employee extends Person{
private double salary;
public Employee(String name, int age , double salary){
super(name,age); //super調用超類構造器(scala中不行)
this.salary = salary;
}
}
2.繼承
extends擴展類、final關鍵字和Java 中相同 。
重寫方法時必須用override,調用超類的方法和java一樣super.toString
2.1.抽象類
子類中重寫超類的抽象字段、抽象方法時,不需要override關鍵字
abstract class Person(val name: string){ //含有一個抽象方法的類必須聲明爲abstract
def id: Int //抽象方法--沒有方法體。不同於java,不用使用abstract關鍵字
var name: String //抽象字段--沒有初始值的字段。
}
2.2.構造順序和提前定義
超類中用到了子類重寫的字段,導致數據出錯:
class Creature{
val range: Int = 10 //子類重寫的字段
val env: Array[Int] = new Array[Int](range) //超類中用到了
}
class Ant extends Creature{
override val range = 2
}
結果range=2,env長度爲0
解決辦法:
1.將val聲明爲final。這樣很安全但並不靈活
2.在超類中將val聲明爲lazy。這樣很安全但並不高效。
3.在子類中使用提前定義語法:
class Ant extends{override val range = 2} with Creature
3.對象
3.1.單例對象(java靜態類)
Scala單例對象是十分重要的,沒有像在Java一樣有靜態類、靜態成員、靜態方法,但是Scala提供了object對象,這個object對象類似於Java的靜態類,它的成員、它的方法都默認是靜態的。
object SingletonDemo {
def main(args: Array[String]) {
//SessionFactory爲單例對象,不需要new,用【類名.方法】調用對象中的方法
val session = SessionFactory.getSession()
println(session)
}
}
object SessionFactory{
//該部分相當於java中的靜態塊
var counts = 5
val sessions = new ArrayBuffer[Session]()
while(counts > 0){
sessions += new Session
counts -= 1
}
//在object中的方法相當於java中的靜態方法
def getSession(): Session ={
sessions.remove(0)
}
}
class Session{
}
3.2.伴生對象和伴生類
伴生類和伴生對象之間可以相互訪問私有的方法和屬性
class Dog {
val id = 1
private var name = "itcast"
def printName(): Unit ={
//在Dog類中可以訪問伴生對象Dog的私有屬性
println(Dog.CONSTANT + name )
}
}
//伴生對象
object Dog {
//伴生對象中的私有屬性
private val CONSTANT = "汪汪汪 : "
def main(args: Array[String]) {
val p = new Dog
//訪問私有的字段name
p.name = "123"
p.printName()
}
}
3.3.apply方法
class ApplyDemo{
def apply() = "apply in class"
def test{
println("test")
}
}
object ApplyDemo {
def stat{
println("static method")
}
def apply() = new ApplyDemo
var count = 0
def incc = {
count += 1
}
}
object Main extends App{ //擴展App特質,代替main方法
ApplyDemo.stat
val a = ApplyDemo()//類名後面加括號,相當於調用伴生對象的apply方法
a.test
a()//對象加括號相當於調用對象的apply方法
for(i <- 0 until 10){
ApplyDemo.incc
}
println(ApplyDemo.count)
}
3.4.擴展Enumeration類來實現枚舉
枚舉:比如星期幾,如果設置爲數字類型,那麼如何控制數字的範圍呢?而枚舉類型則可以將一個類型限制在可控制的範圍內。
定義一個擴展Enumeration類的對象並以value方法調用初始化枚舉中的所有可選
值。例如:
object TrafficLightColor extends Enumaration{
val Red,Yellow,Green = Value
}
在這裏定義了三個字段:red、Yellow和Green,然後用value調用將它們初始化。這是如下代碼的簡寫;
val Red = Value
val Yellow = Value
val Green = Value
每次調用value方法都返回內部類的新實例,該內部類也叫做Value。或者也可以向value方法傳人ID、名稱,或兩個參數都傳
val Red = Value(0,“Stop”) //ID爲0,名稱爲Stop
val Yellow = Value(10) //默認名稱爲Yellow
val Green = Value("go") //默認ID爲11(前一個加1)
接下來可以用TrafficLightColor .Red引用枚舉值,或者直接import TrafficLightColor._
參看資料:《快學Scala》
公衆號:大叔據 。
評論不能及時回覆可直接加公衆號提問或交流,知無不答,謝謝 。
歡迎關注大叔