首页 > 代码库 > 快学Scala(5)--类
快学Scala(5)--类
构造简单类:
class Counter { private var value = http://www.mamicode.com/0>
在主函数中调用类:
def main(args: Array[String]): Unit = { val myCounter = new Counter myCounter.increment println(myCounter.current) }
注:当调用无参方法时,可以写圆括号也可以不写;推荐对于改值器方法(即改变对象状态的方法)使用(),对于取值器方法(不会改变对象状态的方法)去掉()是个不错的选择,例如:
myCounter.increment() println(myCounter.current)
注:可以通过不带()的方式声明current来强制这种风格
def current = value //类的使用者必须使用myCounter.current,不带圆括号
Scala中带getter和setter的属性
对于简单类Person来说:
class Person { var age = 0 }
默认getter和setter调用方法:
println(p.age) //将调用方法p.age() p.age = 20 //将调用p.age=(20)
也可以自定义getter和setter方法:
class Person { private var privateAge = 0
//getter -> age def age = privateAge //setter -> age_= 注意age_和=之间不能有空格 def age_= (newValue : Int) { if(newValue > privateAge) privateAge = newValue } }
若对于某个属性只希望有getter方法,不希望有setter方法,但可以通过特定的其他方式被改变
class Counter { private var value = http://www.mamicode.com/0 > def increment() { value +=1 } def current = value //声明中没有() }
总结:在实现属性时有四个选择
1. var foo: Scala自动合成一个getter和一个setter
2. val foo: Scala自动合成一个getter
3. 由你来定义foo和foo_=方法
4. 由你来定义foo方法
对象私有字段:
private[this] var value = http://www.mamicode.com/0>
类的方法只能访问到当前对象的value字段,而不能访问同一类型的其他对象的该字段,这种访问被称作对象私有的。
注:对于类私有的字段,Scala生成私有的getter和setter方法;而对于对象私有的字段,Scala根本不会生成getter或setter方法
不过,private[类名]修饰符可以定义仅有指定类的方法可以访问给定的字段。这里的类名必须是当前定义的类,或者是包含该类的外部类
Bean属性:
@BeanProperty var name: String = _ //name属性值为null
将会生成四个方法:
1. name: String
2. name_=(newValue: String): Unit
3. getName(): String
4. setName(newValue: String): Unit
辅助构造器:
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) //第二个辅助构造函数
主构造函数:
class Person(val name: String, private var age: Int) { println("Just constructed another person") def description = name + " is " + age + " years old" }
如果类名之后没有参数,则该类具备一个无参主构造器。这样一个构造器仅仅是简单的执行类体中的所有语句而已。
如果不带val或var的参数至少被一个方法所作用,它将被升格为字段,等同于private[this] val字段的效果
否则,该参数将不被保存为字段,它仅仅是一个可以被主构造器中的代码访问的普通参数
如果使用 class Person private (val id: Int) { ... }, 则主构造器私有,类用户必须通过辅助构造器来构造Person对象
嵌套类:
class NetWork { class Member(val name: String) { val contacts = new ArrayBuffer[Member] } private val menbers = new ArrayBuffer[Member] def join(name: String) = { val m = new Member(name) menbers += m m } }
调用:
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 //不可以这样做--不能将一个myFace.Member添加到chatter.Member元素缓冲当中 }
问题:每一个实例都有它自己的Member类,就和他们有自己的member字段一样,也就是说是两个类
解决方法: 1. 伴生对象(第六章)
2. 类型投影
class Network { class Member(val name: String) { val contacts = new ArrayBuffer[Network#Member] } ... }
快学Scala(5)--类