7.Scala-类
第7章 类7.1 简单类和无参方法类的定义可以通过 class 关键字实现,如下: ? class Dog { private var leg: Int = _ def shout(msg: String) = { println(msg) } def currentLeg = leg } ? ? 使用这个类: val dog = new Dog dog shout "wangwang" println(dog currentLeg) ? ?
注:在 Scala 中,类并不声明为 Public,一个 Scala 源文件可以包含多个类。所有
这些类都具有公有可见性。调用无参方法时,可以加(),也可以不加;如果方法
定义中不带括号,那么调用时就不能带括号。
? 7.2 Getter、Setter 方法
对于 scala 类中的每一个属性,编译后,会有一个私有的字段和相应的
getter、setter 方法生成,比如:?
//getter println(dog leg) //setter dog.leg_= (10) println(dog currentLeg) ?当然,你可以不使用自动生成的方法,自己定义 getter 和 setter 方法 ? class Dog2 { private var _leg = 4 def leg = _leg def leg_=(newLeg: Int){ _leg = newLeg } } ? 使用之: val dog2 = new Dog2 dog2.leg_=(10) println(dog2.leg) ? 尖叫提示:自己动手创建变量的 getter 和 setter 方法需要遵循以下原则: 1)字段属性名以 "_" 作为前缀,如:_leg 2)getter 方法定义为:def leg = _leg 3)setter 方法定义时,方法名为属性名去掉 前缀,并加上后缀发,后缀时:"leg_=",如例子所示 ? ? ? ? ? ? 7.3 对象私有字段package unit7 package society { package professional{ class Executive { private[professional] var workDetails = null private[society] var friends = null private[this] var secrets = null ? ? ? ? ? ? 7.4 Bean 属性
JavaBeans 规范定义了 Java 的属性是像 getXXX()和 setXXX()的方
法。许多 Java 工具都依赖这个命名习惯。为了 Java 的互操作性。将 Scala 字
段加@BeanProperty 时,这样的方法会自动生成。
?
1)创建一个 Bean,使用@BeanProperty 注解标识某个属性变量
import scala.beans.BeanProperty class Person { @BeanProperty var name : String = _ } ?
?
2)通过 getMane、setName 访问属性
val fred = new Person fred.setName("Fred") fred.getName println(fred.name) ? 尖叫提示:?
Person 将会生成四个方法:
1、name:String
2、name_=(newValue:String): Unit
3、getName():String
4、setName(newValue:String):Unit?
?
? ? ? 7.5 构造器
Scala 的类构造器分为主构造器和辅助构造器。?
?
1) 主构造器的参数直接放置在类名之后:?
定义类: class ClassConstructor(var name: String,private var price: Double){ def myPrintln = println(name + "," + price) } 执行: val classConstructor = new ClassConstructor("hello",20.5) ClassConstructor.myPrintln ?
?
?
?
2) 主构造器会执行类定义中的所有语句:?
class ClassConstructor2(val name: String = "",val price: Double = 0){ println(name + "," + price) } 执行: val ClassConstructor2 = new ClassConstructor2("aa",20) val ClassConstructor2_2 = new ClassConstructor2() ?
?
?
?
3) 通过 private 设置主构造器的私有属性:?
参考1) ?
?
?
?
4) 如果不带 val 和 var 的参数至少被一个方法使用,该参数将自动升级为字段,这时,name 和 price 就变成了类的不可变字段,
而且这两个字段是对象私有的,这类似于 private[this] val 字段的效果。
否则,该参数将不被保存为字段,即实例化该对象时传入的参数值,不会被保留在实例化后的对象之中。
?
?
?
如果想让主构造器变成私有的,可以在()之前加上 private,这样用户只能通过辅助构造器来造对象了
class ClassConstructor private (val name:String,val age:Int) { println(name,age) } ?
?
5) 辅助构造器名称为 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 } def description = name + "is" + age + "years old" } ?
?
?
?
? 7.6 嵌套类即,在 class 中,再定义一个class,以此类推。 Java 中的内部类从属于外部类。Scala中内部类从属于实例。 ? 1)创建一个嵌套类,模拟局域网的聊天场景 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 } } ? ? 2)使用该嵌套类 //创建两个局域网 val network1 = new Network val network2 = new Network //nick 和 alice 加入局域网1 val nick = network1.join("Nick") val alice = network1.join("Alice") //jone 加入局域网2 val jone = network2.join("Jone") //nick 和 alice 互相添加为好友 val nick = network1.join("Nick") val alice = network1.join("Alice") //nick.contacts += jone //这样不行,nick 和 jone 不属于同一个局域网,即, nick 和 jone 不是同一个 class Member 实例化出来的对象 ? 在 Scala 中,每一个实例都有它自己的Menber类,就和他们有自己的 members 字段一样。也就是说, network1.Member 和?network2.Member 是不同的两个类。也就是所谓的: 路径依赖类型,此处需要详细解释。 如果想让 members 接受所有实例的Member,一般有两种办法: ? 1)将 Member 作为Network 的伴生类对象存在 创建类: import scala.collection.mutable.ArrayBuffer class Network { val contacts = new ArrayBuffer[Network.Member]() //用于存放局域网中的对象 val members = new ArrayBuffer[Network.Member]() def join(name: String) = { val m = new Network.Member(name) members += m m } } object Network{ class Member(name: String){ //用于存放某个Mem对象的联系人 val contacts = new ArrayBuffer[Member]() } } ? ? ? 2)使用类型投影,注意留意关键符号:"#" 创建类: import scala.collection.mutable.ArrayBuffer class Network { class Member(name: String){ //用于存放某个Mem对象的联系人 val contacts = new ArrayBuffer[Network#Member]() } //用于存放局域网中的对象 val members = new ArrayBuffer[Network#Member]() def join(name: String) = { val m = new Member(name) members += m m } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |