5.1简单类和无参方法
定义类
class Counter{ //不声明为public,但仍具有公共可见性
private var value = 0 //必须初始化字段
def increment(){value += 1} //方法是公有的
def current() = value //这里也可以定义为 def current = value ,调用时则强制不能带()
}
构造对象及调用无参方法
val myCounter = new Counter //或new Counter()
myCounter.increment() //或myCounter.increment,圆括号可有可无,一般对于改值器使用(),对于取值器去掉()
println(myCounter.current)
5.2 带getter和setter的属性
5.2.1 属性通过setter来设置的好处。
getter和setter作用在于可以对类的属性做一些限制性措施,防止对属性的任意更改。
java中:
public class Test1 {
private int age; //test1.age = 10 这样可以设置age属性
public void setAge(int age){ //同时还可以test1.setAge(10)这样设置age属性。
this.age = age;
}
public void setAge(int age) { //这样就可以对age属性做一些限制,防止属性值设置混乱。
if (age > 10) {
this.age = age;
} else
this.age = 0;
}
5.2.2 scala中的setter和getter
scala中类的每个属性,在编译的时候都会生成一对getter和setter方法,当然也可以重写getter和setter方法,如果属性被定义为private,getter和setter则也是private。
属性不能被public修饰,因为默认就是public的。当然也可以控制属性不自动生成getter和setter,后面章节会涉及。
class Person {
var age = 0
}
hadoop@ubuntu1:~/scalaTest$ javap -private Person //查过经过编译后的多出来了三项内容,setter和getter,还有个是默认构造器
Compiled from "Person.scala"
public class Person {
private int age;
public int age(); //getter,
public void age_$eq(int); //setter,名字为age_=(),在scala中使用的=号,在jvm中并不支持在方法名中带有=,而被翻译成了$eq
public Person();
}
val person = new Person()
person.age_=(10) //调用setter方法
person.age //调用getter方法
自己重新定义getter和setter方法
class Person{
private var privateage =0
def age = privateAge //重新定义getter,age没有带括号,调用时只能是person.age
def age_= (x : Int){ //重新定义setter
if(x > privateAge) privateAge = x; //不能变年轻
}
}
5.3 只带getter的属性
只允许客户端查看属性,而不能让客户端设置属性
通过private来限制客户端更改类的属性值,但仍可以在类的内部改变,另一种是用val来让其永不改变。val定义的属性不生成setter。
class Counter{
private var value = 0 //private定义的属性会生成私有的setter和getter
def increment()={value += 1}
def current = value //内部作改变成立
}
val counter1 = new Counter()
counter1.value_=(10) //这样则会报错:error: variable value in class Counter cannot be accessed in Counter
counter1.value //这样也会报同样的错
counter1.current //获取value的值,这样可以看value,就可以只能在客户端看value,而不能改变其value
5.4 对象私有字段
同java一样,scala的方法可以访问该类的所有对象的私有属性。
class Counter{
private var value = 0
def increment(){value += 1}
def compare(counter:Counter)={counter.value < value}
}
counter1.compare(counter2) //新建两个对象,则都可以访问value属性。counter2的value小则返回true
如果这样:则新建的对象counter1、2则不能访问value,报错。
class Counter{
private[this] var value = 0
def increment(){value += 1}
def compare(counter:Counter)={counter.value < value}
}
private[this] var value = 0 //这样定义的属性,Counter类的方法只能访问到当前对象的value属性,而不能访问同样是Counter类型的其他对象的该属性。这样的属性被称为对象私有的。
5.5 Bean属性
import scala.beans.BeanProperty
class Person{
@BeanProperty var age = 0
}
将会生成四个方法:
hadoop@ubuntu1:~/scalaTest$ javap Person
Compiled from "person1.scala"
public class Person {
public int age();
public void age_$eq(int);
public void setAge(int);
public int getAge();
public Person();
}
5.6 辅助构造器
scala中分主构造器和辅构造器
辅构造器:与java不同的是名称为this ,必须以一个先前已定义的其他辅助构造器或主构造器的调用开始
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
}
}
5.7 主构造器
主构造器的参数直接放置在类名之后:
class Person(val name:String,val age:Int){...} //如果不定义主构造器,默认为无参的person()
class Person(val name:String,val age:Int){
println("Just constructed another person") //主构造器会执行类定义中的所有语句,对象被构造出来后这段代码就会被执行
}
class prinvate Person(val name:String,val age:Int){...} //私有的主构造器,这样的定义方式只有通过辅助构造器来构造person对象
5.8 嵌套类
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
}
}
val chatter = new Network //在scala中,每个实例都有自己的member类,就跟member属性一样。chatter.Member和myFace.Member是两个不同的两个类
val myFace = new Network
val fred = chatter.join("Fred") //向chatter这个network类里添加Fred Member
val wilma = chatter.join("Wilma") //
fred.contacts += wilma //ok
val barney = myFace.join("Barney") //类型为myFace.Member
fred.contacts += barney //不可以这样做,不能讲myFace.Member添加到chatter.Member元素缓冲中