classCounter{//字段必须初始化private var value =0//方法默认公有
def increment(): Unit ={
value+=1}
def current()=value
}//使用类构造对象
val myCounter=newCounter
myCounter.increment()
myCounter.increment()println(myCounter.current)
Compiled from "Person2.scala"publicclassPerson2{privateint privateAge;privateintprivateAge();privatevoid privateAge_$eq(int);publicintage();publicvoid age_$eq(int);publicPerson2();}
如果字段是私有的,那么getter和setter方法也是私有的
如果字段是val,则只有getter方法生成
如果不生成任何getter和setter,可以将字段声明为private[this]
只带getter属性
将字段声明为val,只生成一个final修饰的私有字段和一个公有的getter方法。
例如
//Person3.scalaclassPerson3{
val name="aa"}//查看的字节码
Compiled from "Person3.scala"publicclassPerson3{privatefinal java.lang.String name;public java.lang.String name();publicPerson3();
var foo:自动合成getter和setter方法
val foo:自动合成一个getter方法
不能实现只有setter没有getter
自己定义foo和foo_=
对象私有字段
默认情况下,同一个类的一个对象可以访问另一个对象的私有字段
classCounter{//字段必须初始化private var value :Int =0//方法默认公有
def increment(): Unit ={
value+=1}
def current():Int=value
//可以访问另一个对象的私有字段value
def isLess(other:Counter):Boolean ={ value < other.value }}
//Person4.scalaclassPerson4{private var age =0private[this] var card =0}//编译后
Compiled from "Person4.scala"publicclassPerson4{privateint age;privateint card;privateintage();privatevoid age_$eq(int);publicPerson4();}
//Person5.scalaimport scala.beans.BeanProperty
classPerson5{@BeanProperty var age =0}//查看
Compiled from "Person5.scala"publicclassPerson5{privateint age;publicintage();publicvoid age_$eq(int);publicvoidsetAge(int);publicintgetAge();publicPerson5();}
总结一下
序号
scala字段
生成的方法
何时使用
1
val / var name
公有的name,name_=(对于var)
实现一个公开访问并背后是字段形式保存的属性
2
@BeanProperty val / var name
公有的name,name_=(对于var),getName,setName(对于var)
与JavaBeans互操作
3
private val / var name
私有的name,name_=(对于var)
字段的访问限制在本类的方法
4
private[this] val / var name
不生成
字段访问限制在同一个对象,不经常用到
5
private[类名] val / var name
依赖于具体实现
字段访问赋予外部类,不经常用到
各种可能的情况查看一下
//Person6.scalaimport scala.beans.BeanProperty
classPerson6{
var name1 =0
val name2 =0private var name3 =0private val name4 =0@BeanProperty var name5 =0@BeanProperty val name6 =0private[this] var name7 =0private[this] val name8 =0}//字节码
Compiled from "Person6.scala"publicclassPerson6{privateint name1;privatefinalint name2;privateint name3;privatefinalint name4;privateint name5;privatefinalint name6;privateint name7;privatefinalint name8;publicintname1();publicvoid name1_$eq(int);publicintname2();privateintname3();privatevoid name3_$eq(int);privateintname4();publicintname5();publicvoid name5_$eq(int);publicvoidsetName5(int);publicintname6();publicintgetName5();publicintgetName6();publicPerson6();
主构造器的字段需要JavaBeans的getter和setter方法
class Person(@BeanProperty var name:String)
辅助构造器
scala可以有任意多的构造器
最重要的构造器:主构造器
辅助构造器可以有很多
辅助构造器的名称为this,(java或C++中构造器的名称和类名相同,修改类名时不方便)
每一辅助构造器必须以一个对先前定义的其他辅助构造器或主构造器的调用开始
classPerson{private var name =""private var age =0println("主构造器")//第一个辅助构造器
def this(name:String){//调用主构造器this()println("执行第一辅助构造器")this.name=name
}//第二个辅助构造器
def this(name:String,age:Int){//调用第一个辅助构造器this(name)println("执行第二辅助构造器")this.age=age
}}//调用
val p1 =newPerson()println("---")
val p2 =newPerson("及时雨宋江")println("------")
val p3 =newPerson("玉麒麟卢俊义",43)//输出的结果
主构造器
---
主构造器
执行第一辅助构造器
------
主构造器
执行第一辅助构造器
执行第二辅助构造器
如果想私有主构造器,可以在参数列表前面加入private关键字,这样就只能通过辅助构造器构造对象class Person private(val name:String,val age:Int)
主构造器参数
生成的字段/方法
name:String
如果有方法使用name,则变为对象私有字段 ,否则不生成字段。从不生成方法
private val / var name:String
私有字段,私有的getter、setter方法(对于var)
val / var name:String
私有字段,公有的getter、setter方法(对于var)
@BeanProperty val / var name:String
私有字段,公有的Scala版和JavaBeans版getter、setter方法
// Person3.scalaimport scala.beans.BeanProperty
classPerson3(val name1:Int,
var name2:Int,
name3:Int,
name4:Int,private var name5:Int,private val name6:Int,@BeanProperty var name7:Int,@BeanProperty val name8:Int){
def descrption ="name3 is "+name3
}//得到的方法和字段//所有的字段全部为私有,getter或setter有私有也有公有。
Compiled from "Person3.scala"publicclassPerson3{privatefinalint name1;privateint name2;privatefinalint name3;privateint name5;privatefinalint name6;privateint name7;privatefinalint name8;publicintname1();publicintname2();publicvoid name2_$eq(int);privateintname5();privatevoid name5_$eq(int);privateintname6();publicintname7();publicvoid name7_$eq(int);publicvoidsetName7(int);publicintname8();public java.lang.String descrption();publicintgetName7();publicintgetName8();publicPerson3(int,int,int,int,int,int,int,int);
嵌套类
一个外部类的不同对象的内部类是不同的
classNetwork{classMember(val name:String){
val contacts=newArrayBuffer[Member]}private val members=newArrayBuffer[Member]
def join(name:String): Member ={
val m =newMember(name)
members += m
m
}}//
val chatter =newNetwork
val myFace =newNetwork
val fred = chatter.join("Fred")
val wilma = chatter.join("Wilma")
fred.contacts += wilma
val barney=myFace.join("Barney")// fred.contacts += barney //错误
如果实现内部类可以相互访问,使用伴生对象,这样fred和barney就可以添加好友了。
classNetwork{private val members=newArrayBuffer[Network.Member]
def join(name:String): Network.Member ={
val m =newNetwork.Member(name)
members += m
m
}}
object Network{classMember(val name:String){
val contacts=newArrayBuffer[Member]}}