scala学习笔记 - 类属性

25 篇文章 0 订阅
15 篇文章 2 订阅

Scala类的属性

Scala类最简单的形式看上去和Java或C++中的很相似:

class Demo1 {
  private var value = 0 // 必须初始化字段

  def increment(): Unit = { // 方法默认是共有的
    value += 1
  }
  //  def current(): Int = value
  def current: Int = value
}

调用无参方法(比如current时,可以写上圆括号,也可以写;?一般认为对于改值器方法(即改变对象状态的方法)使用(),而对于取值器方法(不会改变对象状态的方法)去掉()是不错的风格;可以通过以不带()的方式 current来强这种风格。

Scala对每个字段都提供了类似于getter和setter的方法,如下:

class Demo2 {
  // 必须初始化字段
  private var value1 = 0
  var value2 = 0
  val value3 = 0
  private[this] var value4 = 0
}

编译后的class文件:

public class Demo2
{
  private void value1_$eq(int x$1)
  {
    this.value1 = x$1;
  }
  
  private int value1()
  {
    return this.value1;
  }
  
  private int value1 = 0;
  
  public void value2_$eq(int x$1)
  {
    this.value2 = x$1;
  }
  
  public int value2()
  {
    return this.value2;
  }
  
  private int value2 = 0;
  
  public int value3()
  {
    return this.value3;
  }
  
  private final int value3 = 0;
  private int value4 = 0;
}

可以发现:

  • 如果属性是private修饰,则getter和setter方法也是私有的。
  • 如果属性是val修饰,则只有getter方法被生成;只读属性,有getter没有setter,属性的值在对象构建完成后就不在改变。不过也可以使用Demo1的方式修改。
  • 如果不需要getter和setter方法,可以将属性声明为private[this]。

在scala中,方法可以访问该类的所有对象的私有字段。例如:

class Demo3 {
  private var value = 0

  def increment(): Unit = {
    value += 1
  }

  def isLess(other: Demo3): Boolean = value < other.value
}

之所以访问other.value是合法的,是因为other也同样是Demo3对象。
Scala允许我们定义更加严格的访问限制,通过private[this]这个修饰符来实现。例如:

class Demo3 {
  /**
   * 这样一来, Demo3的方法只能访问到当前对象的value字段,而不能访问同样是Demo3型的其他对象的该宇段;这样的访问有时被称为对象私有的。
   */
  private[this] var value = 0

  def increment(): Unit = {
    value += 1
  }
//  def isLess(other: Demo3): Boolean = value < other.value 会报错
}

对于类私有的属性, Scala生成私有的getter和setter方法;但对于对象私有的属性,Scala根本不会生成getter和setter方法。

Scala对于你定义的字段提供了getter和setter方法;不过 ,这些方法的名称并不是Java工具所预期的;许多Java工具都依赖这样的命名习惯。当你将Scala属性标注为@BeanProperty时,这样的方法会自动生成。例如:

import scala.beans.BeanProperty
class Demo4 {
  @BeanProperty var value: String = _
}

编译后的class文件:

public class Demo4
{
  private String value;
  
  public String getValue()
  {
    return value();
  }
  
  public void setValue(String x$1)
  {
    this.value = x$1;
  }
  
  public void value_$eq(String x$1)
  {
    this.value = x$1;
  }
  
  public String value()
  {
    return this.value;
  }
}

总结

字段生成的方式:

Scala字段生成的方法何时使用
val / var name公有的name
name_ = (仅限于var)
实现一个可以被公开访问并且背后是以字段形式保存的属性
@BeanProperty val / var name公有的name
getName()
name_ = (仅限于var)
setName(…) (仅限于var)
与JavaBeans互操作
private val / var name私有的name
name_ = (仅限于var)
用于将属性访问限制在本类的方法,就和Java一样。尽量使用private,除非你真的需要公有的属性
private[this] val / var name用于将字段访问限制在同一个对象上调用的方法
private[类名] val / var name依赖于具体实现将访问权赋予外部类

参考:快学scala(第二版)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值