Scala与Java差异(六)之类定义
一、類定義
(1)定義類,包含field以及方法
class ScalaClass {private var field = "one"def aMethod() { print("field : " + field ) } ?def getField = field }(2)調用對象方法
val scalaClass?= new ScalaClassscalaClass.aMethod()print(scalaClass.getField) // 也可以不加括號,如果定義方法時不帶括號,則調用方法時也不能帶括號
(3)getter與setter
1)var
此時scala生成的面向JVM的類時,會定義為private的name字段,并提供public的getter和setter方法。如:var field
2)val
只會生成getter方法。如:val field
3)private
生成的getter和setter也是private的,與java的私有屬性變量類內訪問一致。如:private var field
4)private[this]
不生成setter和getter方法,并且只是當前對象能夠訪問,與java的私有屬性變量類內訪問不一致。如:private[this] var field
5)自定義getter與setter方法
定義setter方法,def field_=(val: type){? ?},自定義setter方法的時候注意scala的語法限制,簽名、=、參數間不能有空格
定義getter方法,def field=xxx
class Person{private var lastName = "mk"def name = lastName def name_=(newVal: String) ?{lastName=newVal}}val mk = new Personprint(mk.name)mk.name = "xx"// 調用getter和setter方法,分別叫做name和name_ =6)Java風格的getter和setter方法
Scala的getter和setter方法的命名與java是不同的,是field和field_=的方式
讓scala自動生成java風格的getter和setter方法,只要給field添加@BeanProperty注解即可
此時會生成4個方法,name: String、name_=(newValue: String): Unit、getName(): String、setName(newValue: String): Unit
import scala.reflect.BeanPropertyclass Person{@BeanProperty var name: String = _}class Person(@BeanProperty var name: String)val s = new Persons.setName("MK")s.getName()7)輔助constructor
Scala中,可以給類定義多個輔助constructor,類似于java中的構造函數重載
輔助constructor之間可以互相調用,而且必須第一行調用主constructor
8)主constructor
Scala中,主constructor是與類名放在一起的,與java不同
而且類中沒有定義在任何方法或者是代碼塊之中的代碼,就是主constructor的代碼,沒有java構造方法清晰
class Person(val name: String, val age: Int) {println("name:" + name + ", age:" + age)}主constructor中還可以通過使用默認參數,來給參數默認的值
class Person(val name: String = "MK", val age: Int = 18) {println("name:" + name + ", age:" + age)}主constrcutor傳入的參數什么修飾都沒有,比如name: String,那么如果類內部的方法使用到了,則會聲明為private[this] name;否則沒有該field,就只能被constructor代碼使用
?
二、對象object
object,相當于class的單個實例,在里面定義一些靜態的field或者method(等價于java的定義靜態變量和靜態方法的類)
第一次調用object的方法時,就會執行object的constructor(即object內部不在method中的代碼)。object不能定義接受參數的constructor
object通常用于作為單例模式的實現,或者放class的靜態成員,比如工具方法
object Num {private val zero = 0println("init Number object!")def getZero = zero}(1)?伴生對象
有一個class,還有一個與class同名的object,那么就稱這個object是class的伴生對象,class是object的伴生類
伴生類和伴生對象必須存放在一個.scala文件之中
伴生類和伴生對象,最大的特點就在于,互相可以訪問private field
(2)object繼承抽象類
object的功能其實和class類似,除了不能定義接受參數的constructor之外,object也可以繼承抽象類,并覆蓋抽象類中的方法
abstract class Animal(var name: String) {def toStr(): String }object Cat extends Animal("cat") {override def toStr() = name }(3)?apply方法
apply方法通常在伴生對象objec中實現apply方法實現構造伴生類的對象的功能。
而創建伴生類的對象時,一般不會使用new ClassName的方式,而是使用ClassName()的方式,隱式地調用伴生對象得apply方法,這樣會讓對象創建更加簡潔
比如,Array類的伴生對象的apply方法就實現了接收可變數量的參數,并創建一個Array對象的功能
var arr = Array("a", "b")
class Cat(val name: String) object Cat{def apply(name: String) = new Cat(name) }(4)?main方法
在scala中要運行一個應用程序,那么必須有一個main方法,作為入口(像java中需要編寫一個包含main方法類)
scala中的main方法必須在object中定義,格式為def main(args: Array[String])
object ScalaProgram {def main(args: Array[String]) {println("scala run...")}}除了實現main方法可以作為啟動入口,繼承App Trait類也可以作為啟動入口,然后將需要在main方法中運行的代碼,直接作為object的constructor代碼;而且用args可以接受傳入的參數
object ScalaProgram extends App {println("scala run ...")}運行上面的代碼,需要將其放入ScalaProgram.scala文件,然后先使用scalac編譯,再用scala執行
scalac ScalaProgram.scala
scala -Dscala.time ScalaProgram
App Trait的工作原理:App Trait繼承自DelayedInit Trait,scalac命令進行編譯時,會把繼承App Trait的object的constructor代碼都放到DelayedInit Trait的delayedInit方法中執行。
(5)object實現枚舉
Scala沒有直接提供類似于Java中的Enum類的枚舉特性,如果要實現枚舉,則需要用object繼承Enumeration類,并且調用Value方法來初始化枚舉值
通過Value傳入枚舉值的id和name,通過id和toString可以獲取; 還可以通過id和name來查找枚舉值。使用枚舉object.values可以遍歷枚舉值
object Sex extends Enumeration {val MAN = Value(0, "man")val WOMAN = Value(1, "woman")}Sex(0) Sex.withName("man") for (s <- Sex.values) println(s)?
總結
以上是生活随笔為你收集整理的Scala与Java差异(六)之类定义的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1T 版 3429 元新低:努比亚 Z5
- 下一篇: java美元兑换,(Java实现) 美元