Scala(四)之“类和属性”

主构造函数
Scala中为类创建一个主构造函数和Java中不相同。
一个Scala类的主构造函数是以下的组合:

  • 构造函数参数
  • 在类内部被调用的方法
  • 在类内部执行的语句和表达式

下面的类说明了在类中的构造函数参数、类字段和语句:

class Person(var firstName: String, var lastName: String) {
  println("the contructor begins")

  // some class field
  private val HOME = System.getProperty("use.home")
  var age = 0

  // some method
  override def toString = s"$firstName $lastName is $age years old"
  def printHome{ print(s"HOME = $HOME")}
  def printFullName = {println(this)} // uses toString

  printHome
  printFullName
  println("still in the constructor")
}

注意:Scala中被private修饰的字段,不可以被其他对象直接访问,并且其值也不可以改变。


控制构造函数字段的可见性
var字段:如果一个构造函数参数被声明为var,该字段的值是可变的,Scala会为它生成getter和setter方法。

scala> class Person(var name: String)
defined class Person

scala> val p = new Person("Alvin Alexander")
p: Person = Person@4d1bf319
// getter
scala> p.name
res4: String = Alvin Alexander
// setter
scala> p.name = "gnahznib"
p.name: String = gnahznib

scala> p.name
res5: String = gnahznib

val字段:如果构造函数参数字段被定义为val,那么这个字段一旦被赋值就无法改变,就像Java中的final。因此,有访问方法是很有必要的,但不应该有修改方法。

scala> class Person(val name: String)
defined class Person

scala> val p = new Person("Alvin Alexander")
p: Person = Person@5680a178

scala> p.name
res0: String = Alvin Alexander

scala> p.name = "gnahznib"
<console>:13: error: reassignment to val
       p.name = "gnahznib"
              ^

非val和非var的字段:当构造函数参数既没有声明为val或var是,字段的可见性很受限制,并且Scala不会为此生成访问修改方法。

scala> class Person(name: String)
defined class Person

scala> val p = new Person("Alvin Alexander")
p: Person = Person@16b3fc9e

scala> p.name
<console>:14: error: value name is not a member of Person
       p.name
         ^

给val或var加上private:private关键字会阻止getter和setter方法的生成,所以这个字段只能被类的成员变量使用

scala> class People(private var name: String){def getName{println(name)}}
defined class People

scala> val p = new People("Alvin Alexander")
p: People = People@4493d195

scala> p.name
<console>:14: error: variable name in class People cannot be accessed in People
       p.name
         ^

scala> p.getName
Alvin Alexander

定义辅助构造函数
在类内部以this为名的方法定义辅助构造函数,可以定义多个辅助构造函数,但这些构造函数必须有不同签名(参数列表)。同时,每个构造函数必须调用一个之前已经定义好的构造函数。

  • 辅助构造函数必须使用this命名创建;
  • 每个辅助构造函数必须从调用之前定义的构造函数开始;
  • 每个构造函数必须要有不同的签名;
  • 一个构造函数通过this调用另一个不同的构造函数。

注意:一个辅助构造函数只需要调用之前定义过的构造函数就可以了。

// primary contructor
class Pizza(var crustSize: Int, var crustType: String) {
  // one-arg auxiliary constructor
  def this(crustSize: Int){
    this(crustSize, Pizza.DEFAULT_CRUST_TYPE)
  }

  // one-arg auxiliary constructor
  def this(crustType: String){
    this(Pizza.DEFAULT_CRUST_SIZE, crustType)
  }

  // zero-arg auxiliary constructor
  def this(){
    this(Pizza.DEFAULT_CRUST_SIZE, Pizza.DEFAULT_CRUST_TYPE)
  }

  override def toString: String = s"A $crustSize inch pizza with a $crustType crust"

  object Pizza{
    val DEFAULT_CRUST_SIZE = 12
    val DEFAULT_CRUST_TYPE = "THIN"
  }
}

定义一个私有的主构造函数
在使用单例模式时,需要创建一个私有的主构造函数。
在类名和构造函数接收的任意参数之间插入一个private关键字,就可以创建私有主构造函数。

// 私有的主构造函数
class Brain private{
  override def toString: String = "This is the brain"
}

object Brain {
  val brain = new Brain
  // 在类的伴生对象中实现一个getInstance方法
  def getInstance = brain
}

object SingletonTest extends App{
  val brain = Brain.getInstance
  println(brain)
}

伴生对象:一个伴生对象就是定义在与类的同一个文件中,同时与类有相同的名字的对象。


设置构造函数参数的默认值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值