scala编程实践---类

Posted 汪本成

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了scala编程实践---类相关的知识,希望对你有一定的参考价值。

今天实践一下scala里面类的使用,首先看下目录工程


1、创建一个Person类

代码一:

package Demo

/**
  * Created by 汪本成 on 2016/8/6.
  */

class Person 
  var name: String = _
  var age: Int = 27


object OOPInScala 

  def main(args: Array[String]) 
    var p = new Person
    p.name = "Rockey"
    println(p.name + ":" + p.age)
  

运行结果:

Rockey:27

2、private[this]使用

代码二:

package Demo

/**
  * Created by 汪本成 on 2016/8/6.
  */

class Person 
  var name: String = _
  var age: Int = 27
  private[this] val gender = "male"


object OOPInScala 

  def main(args: Array[String]) 
    var p = new Person
    p.name = "Rockey"
    println(p.name + ":" + p.age + "," + p.gender)
  

代码二中标红的一段代码会出错,运行的话会出现如下图提示的错误


注意:通过代码二的实验,可以知道private[this]定义后的内容无法在外部中使用,这起到了很好的保护作用。

3、简单类和无参方法

代码三:

package Demo

/**
  * Created by 汪本成 on 2016/8/6.
  */

class Person 
  var name: String = _
  var age: Int = 27
  private[this] val gender = "male"


class Counter 
  private var value = 0 // 必须初始化字段
  def increment()  value += 1  // 方法默认公有
  def current() = value


object OOPInScala 

  def main(args: Array[String]) 
    var p = new Person
    p.name = "Rockey"
    println(p.name + ":" + p.age)

    var myCounter = new Counter //new Counter()
    myCounter.increment()
  


1、Scala中的类不声明为public,一个Scala源文件中可以有多个类。

2、调用无参方法时,圆括号是可写可不写的。推荐的做法是:如果是会改变对象状态的方法,就带上();否则,就不带。

3、如果将方法的声明改为def current = value,那么可以强制不能带()(下面要提到的getter就是这种风格的,所以调用getter时,必须不带())

4、getter和setter

代码四:

class People 
  private var privateAge = 0

  def age = privateAge
  def age_(newValue: Int) 
    if (newValue > privateAge) privateAge = newValue
  

  在面向JVM的类中,这个简单的Person类有一个私有的age字段和相应的,公有的getter和setter方法。(如果将age声明为private的,getter和setter方法也是私有的。)Scala中,getter和setter分别叫做age和age_=。

  Scala中,字段和getter/setter间的关系,还有其他几种情况:
1、使用val声明的字段,是只有getter,因为val声明的是不可变的啊。Scala中不能实现只有setter的字段。还有对象私有字段。

2、Scala中,方法可以访问该类的所有对象的私有字段,这一点与Java一样。如果通过private[this]来字段来修饰,那么这个字段是对象私有的,这种情况下,不会生成getter和setter。对象私有字段,只能由当前对象的方法访问,而该类的其他对象的方法是无法访问的。如果说分不清楚对象和类的区别,这里就又要犯浑了。
3、接下来是一种与private[this]相似的访问控制。Scala中可以使用private[class-name]来指定可以访问该字段的类,class-name必须是当前定义的类,或者是当前定义的类的外部类。这种情况会生成getter和setter方法。
4、Bean属性(L1)
使用 @BeanProperty注解来为字段生成符合JavaBeans规范的getter/setter方法。使用该注解后,将会生成4个方法:Scala的getter/setter和JavaBeans规范的getter/setter(如果是val声明,就没有setter部分了)。

import scala.reflect.BeanProperty
// 在Scala 2.10.0之后已被废弃
// 使用scala.beans.BeanProperty代替
class Person 
  @BeanProperty var name: String = _

5、类的构造函数

5.1、主构造器

代码五:

package Demo

/**
  * Created by 汪本成 on 2016/8/6.
  */

class Person 
  var name: String = _
  var age: Int = 27
  private[this] val gender = "male"


class Man(val name: String, val age: Int) 
  println("This is who!")


class Counter 
  private var value = 0 // 必须初始化字段
  def increment()  value += 1  // 方法默认公有
  def current() = value


class People 
  private var privateAge = 0

  def age = privateAge
  def age_(newValue: Int) 
    if (newValue > privateAge) privateAge = newValue
  


object OOPInScala 

  def main(args: Array[String]) 

    var m = new Man("Rocky", 27)
    println(m.name + ":" + m.age)

    var p = new Person
    p.name = "Rockey"
    println(p.name + ":" + p.age)

    var myCounter = new Counter //new Counter()
    myCounter.increment()


  

观察代码五我标红的部分,可以发现,scala类中的主构造器有以下特点:

1、主构造器的参数,是类名后()内的内容;

2、主构造器在定义类的时候定义主构造器中的参数会被编译成类中的字段;

3、主构造器的参数被编译成字段,其值被初始化成构造时传入的参数,可以为这些字段也加上访问控制;

4、主构造器在执行时会执行类中的所有不包含在方法体中的语句,所有语句执行一次;

如果将val去掉,如下

可以发现,程序此时无法运行,这说明 Scala 语言的主构造器具有以下非常重要的特性:

  1、如果在主构造器函数的参数中没有用 val 或者 var 去声明变量,那么此时的变量默认是 private[this] 级别的,只能被类内部访问;

  2、如果没有被方法使用,则被当成一个普通的参数,不升级成字段;

5.2、辅助构造器

代码6:

package Demo

/**
  * Created by 汪本成 on 2016/8/6.
  */

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
  


object OOPInScala 

  def main(args: Array[String]) 
    val p1 = new Person // 主构造器
    val p2 = new Person("Fred") // 第一个辅助构造器
    val p3 = new Person("Fred", 42) // 第二个辅助构造器
    
  

辅助构造器的特性:

1、辅助构是用this来声明的;

2、辅助构造器必须以对已经定义的辅助构造器或主构造器的调用开始;


后续会继续详细整理好干货和大家分享,希望继续关注

以上是关于scala编程实践---类的主要内容,如果未能解决你的问题,请参考以下文章

寒假学习进度十二

原创经验分享(17)编程实践对比Java vs Scala

Scala方法调用中的花括号[重复]

2020寒假学习01 Scala 编程初级实践

函数式编程之实践

何时在 Scala 中缀表示法中使用括号