文档章节

Scala学习之类和属性篇(一):定义类的主构造方法

阿拉德大陆的魔法师
 阿拉德大陆的魔法师
发布于 2016/12/08 16:06
字数 1002
阅读 139
收藏 0

在Scala中直接在类名后面跟上参数,即可定义类的主构造方法。

scala> :paste
// Entering paste mode (ctrl-D to finish)

class Person(var firstName: String, var lastName:String) {
  println("The construct begins.")
  var age = 18
  println(this)
  println("The construct ends.")
  override def toString = s"$firstName $lastName is $age years old."
}

// Exiting paste mode, now interpreting.

defined class Person

接下来我们通过主构造方法来实例化这个类,看看发生了什么。所有定义在类体内部的可执行性代码都被执行了,也就是说整个类内部都是这个主构造方法的方法体。

scala> val p = new Person("wang", "wei")
The construct begins.
wang wei is 18 years old.
The construct ends.
p: Person = wang wei is 18 years old.

至此,主构造方法的参数和方法体部分都已经说明了。

接下来我们尝试访问一下类的几个属性,你会发现可以直接用类名加属性名来访问。

scala> p.firstName
res4: String = wang

scala> p.lastName
res5: String = wei

scala> p.age
res6: Int = 18

由于所有属性都是使用var关键字来定义的,所以我们可以改变他们的值。

scala> p.firstName = "Li"
p.firstName: String = Li

scala> p.lastName = "Ming"
p.lastName: String = Ming

scala> p.age = 20
p.age: Int = 20

scala> println(p)
Li Ming is 20 years old.

接下来我们讨论一下主构造方法中参数的可见性问题。

使用var修饰的主构造方法参数,因为是可变的所有Scala会自动为其生成get和set方法。

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

scala> val p = new Person("Ming");
p: Person = Person@25d3cfc8

scala> p.name
res8: String = Ming

scala> p.name = "Ning"
p.name: String = Ning

scala> p.name
res9: String = Ning

使用val修饰的主构造方法参数,因为是不可变的所有Scala不会为其生成set方法。

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

scala> val p = new Person("Ming")
p: Person = Person@5edc70ed

scala> p.name
res10: String = Ming

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

不适用val或者var关键字修饰的主构造方法参数,Scala将采取最严格的访问限制,set和get方法都不会被提供,并且这个参数是不可变的。

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

scala> val p = new Person("Ming")
p: Person = Person@36aa52d2

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

scala> p.name = "Ning"
<console>:15: error: value name is not a member of Person
val $ires8 = p.name
               ^
<console>:13: error: value name is not a member of Person
       p.name = "Ning"
         ^

如果强行为无关键字修饰的主构造方法参数添改变其值的方法,会导致编译报错。

scala> :paste
// Entering paste mode (ctrl-D to finish)

class Person(name: String) {
  def getName = println(name)
  def setName(_name: String) { this.name = _name }
}

// Exiting paste mode, now interpreting.

<console>:13: error: reassignment to val
         def setName(_name: String) { this.name = _name }
                                                ^

在val或者var关键字前面加上private关键字,那么Scala同样不会为这个参数生成get和set方法。那么我们如果想定义一个可变但不可访问的参数该怎么办呢:private var argument。这样Scala不会为其生成set和get方法,但是你可以在类的内部自定义一些方法来改变这个参数的值。

scala> :paste
// Entering paste mode (ctrl-D to finish)

class Person(private var name: String) {
  def printName = println(name)
  def setName(_name: String) { this.name = _name }
}

// Exiting paste mode, now interpreting.

defined class Person

scala> val p = new Person("Ming")
p: Person = Person@5d342959

scala> p.printName
Ming

scala> p.setName("Ning")

scala> p.printName
Ning

总结:主构造方法参数可见性一共有这么几种

  • 使用var修饰:Scala会为其生成get和set方法。
  • 使用val修饰:Scala会为其生成get方法。
  • 不使用修饰:Scala不会为其生成get和set方法,并且参数值不可改变。(效果等同于private val)
  • 使用private修饰:Scala不会为其生成get和set方法,但参数可变性由var和val来决定。

注意:使用case class来定义的类的主构造方法参数,如果你不适用任何修饰默认使用val修饰。

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

scala> val p = new Person("Ming")
p: Person = Person(Ming)

scala> p.name
res15: String = Ming

scala> p.name = "Ning"
<console>:14: error: reassignment to val
       p.name = "Ning"
              ^

 

© 著作权归作者所有

阿拉德大陆的魔法师
粉丝 27
博文 91
码字总数 83019
作品 0
西城
程序员
私信 提问
Scala学习之类和属性篇(三):单例与私有构造函数

我们知道,要想使用单例那么就必须定义私有构造函数来防止从类的外部来创建类的实例。在Scala中你也可以通过private关键字定义类的私有主构造函数来防止从类的外部创建类的实例。 你可能发现...

阿拉德大陆的魔法师
2016/12/09
77
0
Scala学习目录

字符串篇 1.1 字符串的比较 1.2 使用多行字符串 1.3 字符串的切分 1.4 插值函数 1.5 逐字符处理字符串 1.6 使用正则表达式 1.7 访问字符串特定位置的字符 1.8 使用隐式方法来扩展字符串类 2....

阿拉德大陆的魔法师
2016/04/20
367
0
Scala学习之类和属性篇(五):getter和setter方法

Scala会根据你定义属性时候使用的关键字:var,val,private来选择是否自动生成getter和setter方法。并且不允许你重写Scala的setter和getter方法。如果你要重写这两个方法你会看到如下编译错...

阿拉德大陆的魔法师
2016/12/10
1K
0
Scala学习之类和属性篇(二):定义类的辅助构造方法

在Scala中定义主构造函数使用this关键字: 每一个辅助构造函数都需要调用之前定义的任何一个构造函数 每一个辅助构造函数都要有不同的参数表 一个构造函数使用this关键字调用另一个构造函数 ...

阿拉德大陆的魔法师
2016/12/09
150
0
Scala 学习之面向对象(3)

==> 类 ---> 类的定义 class Student{ // 定义属性 private var stuName:String = "Tom" private vat stuAge:Int = 18 // 定义方法 def getStuName():String = stuName def setStuName(newNa......

菜鸟的征程
2018/07/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Redis缓存NoSQL

redis的应用场景有哪些 1、会话缓存(最常用) 2、消息队列,比如支付 3、活动排行榜或计数 4、发布、订阅消息(消息通知) 5、商品列表、评论列表等

BobwithB
11分钟前
2
0
「绘画技巧」一分钟画出动漫人物的喜怒哀乐中“喜”的各种表情

「绘画技巧」一分钟画出动漫人物的喜怒哀乐中“喜”的各种表情 表情拥有着可以凸显动漫人物情绪和主张的魔力,表情渲染整个环境。那么今天来和大家一起分享自己整理收集动漫人物喜怒哀乐中的...

知北
14分钟前
3
0
从流中的三种求和方式谈起

//使用reduce()方法int reduce = Arrays.asList(ins).stream().reduce(0, Integer::sum);//Collectors类的工厂方法,收集器int collect1 = Arrays.asList(ins).stream().collect(Colle......

我的眼里只有眼屎
15分钟前
2
0
File类的使用(文件与文件夹,获取,判断存在,删除,)

//File类的使用 public static void main(String[] args) throws IOException, ClassNotFoundException { //test3();// File f = new File("E:\\资料\\第二阶段\\d......

zhengzhixiang
19分钟前
2
0
58到家MySQL军规升级版

转载 2018-03-30 58到家DBA 架构师之路 一、基础规范 表存储引擎必须使用InnoDB 表字符集默认使用utf8,必要时候使用utf8mb4 解读: 通用,无乱码风险,汉字3字节,英文1字节 utf8...

xiaolyuh
26分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部