一 : 类的声明与方法
Scala类的声明看上去和Java很相似
代码语言:javascript复制class Person{
private var value = 0 // 字段必须初始化
def addAge(){ value = 1 } // 方法默认是public的
def age() = value
}
在Scala中,类并不声明为public,类都具有公有可见性
使用类需要做的就是构造对象并按照通常的方式来调用方法:
val p = new Person
p.addAge()
println(p.age) // 在调用无参方法时,圆括号可以不写 一般对于修改值得方法加上圆括号,对于取值的方法可以不写圆括号
get/set 方法
类中的字段自动带有getter/setter方法。也可以用定制的getter/setter方法替换掉原来的字段的定义,而不必修改使用的客户端——这就是所谓的“统一访问原则”。
代码语言:javascript复制class persion{
var age = 0 // 声明age属性,默认生成get/set方法
private[this] var privateName = "lisi" // private[this] 修饰的变量只能在当前类中使用
}
只带getter属性
如果需要一个只读属性,有getter但没有setter,属性的值在对象构建完成之后就不在改变,则可以使用val字段
代码语言:javascript复制class person{
val time = new Date // 生成一个final字段和一个getter方法,但没有setter
}
get/set汇总
1:var foo:scala自动生成一个getter和一个setter
2:val foo:scala自动合成一个getter
3:自己定义foo和foo_=方法
4:自定义foo方法
Bean属性
前面提到Sacla定义的字段提供了getter和setter方法,
当我们将scala字段标注为@BeanProperty时,这样的方法会自动,比如:
代码语言:javascript复制class person{
@BeanProperty var name:String = _
}
将会生成四个方法:
1.name:String
2:name=(newValue:String):Unit
3:getName():String
4:setName(newValue:String):Unit
类构造器
主构造器:
在Scala中,每个类都有一个主构造器,主构造器并不以this方法定义,而是与类定义在一起。
1.scala中,主构造器的参数直接放在类名后面
代码语言:javascript复制class person(val name:String,val age:Int){
…..
}
主构造器的参数被编译成自段,其值被初始化成构造时传入的参数,如上面的例子中,name和age成为person类的字段
2:主构造器会执行类定义中的所有语句
构造参数也可以是普通的方法参数,不带val或var,这样的参数如何处理取决于它们在类中如何被定义。
如果不带val或var的桉树至少被一个方法所使用,那么它将是字段
辅助构造器
和java一样,Scala也可以有任意多的构造器
1:辅助构造器的名称为this,在java中辅助构造器的名称与类名相同
2:每一个辅助构造器都必须以一个对先前已定义的其它辅助构造器或主构造器的调用开始
代码语言:javascript复制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
}
}
嵌套类
在scala中,几乎可以在任何语法结构中内嵌任何语法结构,可以在函数中定义函数,可以在类中定义类
代码语言:javascript复制class Network{
class member{
}
}
val net = new NetWork
val nw = new NetWork
和在java中不同,每个实例都有它自己的member类,就和他们有自己member字段一样,在这里net.member 和nw.member 是不同的两个类
对象
在scala中没有静态方法或静态字段,我们可以用object这个语法结构来达到同样的目的,对象定义了某个类的单个实例,包含特性,比如:
代码语言:javascript复制object Accounts{
private var lastNumber = 0
}
我们在调用的时候,直接Accounts.newNum 即可
- 在Java中会使用单例对象的地方,在Scala中都可以用对象来实现
- 作为存放工具函数或常量的地方
- 高效的共享单个不可变实例
- 需要用单个实例来协调某个服务
伴生对象.
在集合那个篇章里面,有讲到一个val list = List("1","2") 其实这个内部就是一个伴生类,
在java中,会用到既有实例方法又有静态方法的类,在Scala中,可以通过类和与类名同名的"伴生"对象来达到同样的目的.比如:
代码语言:javascript复制class Account{
val id = Account.newNum
private var balace = 0.0
def deposit(amount:Double){ balace = amount }
}
object Account{ // 伴生对象
private var lastNum = 0
private var newNum() = { lastNum = 1 ; lastNum }
}
类可以和它的伴生对象相互访问私有特性,且必须是在同一个源文件中
再次回顾apply方法
通常,一个apply方法返回的是伴生类的对象
比如
Array对象定义了apply方法,让我们可以用下面这样的表达式来创建数组
Array("red","gree","yello")
这样我们就省去了构造器,也不用new出一个对象了
实例:
代码语言:javascript复制class Acount private (val id :Int,balance:Double){
private var balance = balace
}
object Acount{ // 伴生对象
def apply(balace:Double) = {
new Aount(newNum(),balace)
}
}
这样我们在调用Acount的时候,可以直接
val account = Account(1000.0)
枚举
在Scalal中没有枚举类型,不过标准库中提供了一个Enumeration的一个助手类,可以用于产出枚举
比如:
定义一个扩展Enumeration类的对象并以Value方法调用初始化枚举中的所有可选值
代码语言:javascript复制object Color extends Enumeration{
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,"hongse")
val Yellow = Value(10) // 名称为 "Yellow" ID为10
val green = Value("gg") // ID 为11 名称为gg
如果不指定,则ID在将前一个枚举值基础上加1,从零开始.缺省名称为字段名
定义完之后,我们可以用Color.Red 这种方式来调用