7.Scala-类
Posted lxl616
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
def help(another: Executive)
println(another.workDetails)
println(another.secrets) //报错访问不到
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 字段的效果。
否则,该参数将不被保存为字段,即实例化该对象时传入的参数值,不会被保留在实例化后的对象之中。
主构造器参数 | 生成的字段/方法 |
name: String |
对象私有字段。如果没有使用 name, 则没有该字段 |
private val/var name: String | 私有字段,私有的 getting 和 setting 方法 |
var name: String | 私有字段,公有的 getting 和 setting 方法 |
@BeanProperty val/var name: String | 私有字段,公有的 Scala版和 Java版的 getting 和 setting 方法 |
如果想让主构造器变成私有的,可以在()之前加上 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
以上是关于7.Scala-类的主要内容,如果未能解决你的问题,请参考以下文章