差异Scala类声明

时间:2019-01-25 07:54:18

标签: scala class declaration

我想问以下这两个类声明有什么区别。

class Person(name: String, age: Int)

class Person() {
  var name: String = ""
  var age: Int = 0
}

2 个答案:

答案 0 :(得分:5)

class Person(name: String, age: Int)

nameage是构造函数参数。因此,它们是:

  • 必需-为了创建Person实例
  • 不可变-值不能更改
  • 私有-(默认情况下),并且无法通过类实例进行访问

class Person() {
  var name: String = ""
  var age: Int = 0
}

nameage是类数据成员。他们是:

  • 在构建过程中未指定-但每个Person实例都具有相同的默认值
  • 可变-因为它们是var变量
  • 公共-(默认),并且可以通过类实例进行访问和修改

那么,有什么区别?几乎所有内容。

答案 1 :(得分:-1)

第一个声明使用nameage作为构造函数参数,但它们不会成为该类的成员,也就是说,您不能编写person.name

对于初学者来说,第二行可以被认为是写class Person(var name: String = " ", var age: Int = 0)的更复杂的方法。它实际上并不能解释为完全相同的东西:您的版本创建的类具有单个构造函数参数和两个公共变量,而我的类具有一个带有2个具有默认值的参数的构造函数。除非您有充分的理由声明自己的方式,否则通常最好编写以下代码:

val person = new Person("Andrew", 11)

val person = new Person()
person.name = "Andrew"
person.age = 11 

这是您的第二个版本会强迫您执行的操作。

请注意,在Scala中,通常将使用值(常量)而不是变量,因此实际上通常使用class Person(val name: String = " ", val age: Int = 0)。对于像这样的简单数据类型,人们通常使用case class

case class Person(name: String, age: Int)

在这种情况下,两个参数都被认为是公共的并且是不可变的。修改人员姓名的唯一方法是使用新名称创建另一个Person实例:

val andrew = Person("Andrew", 11)
val will = andrew.copy(name="Will") # Will is also 11

Case类将自动为您提供正确的equalshashCode实现,以及我上面使用的copy方法。您可以在Internet上轻松找到有关它们的更多信息。