覆盖访问器和mutator方法覆盖

时间:2015-12-30 15:06:06

标签: scala

从Scala Cookbook中可以看出,如果构造函数变量未使用'var'or'val'定义,则默认情况下Scala不会生成访问器和修饰符方法,但在下面的示例中。

1.  class Person2(name : String) {  
2.    def name = name;  
3.    def name_=(aName : String) {name = aName}  
4.   }

我在第2行得到一个编译时间,因为“重载的方法名称需要结果类型”。这是什么意思?我是否重载了名称访问器方法,但是从Cookbook中没有生成访问器和mutator方法。任何人都可以回答这个问题。

2 个答案:

答案 0 :(得分:1)

首先,请注意,class Foo(bar: String)未定义名为bar的成员变量,只定义构造函数参数。 你仍然可以在类中的任何地方使用它,因为整个类定义在构造函数体内,因此,它本质上是一个闭包,但你将无法为它赋值。所以,如果我们在上一个答案中修正错误

class Person2(aName : String) {
   def name = aName
   def name_=(aName : String) = { aName = name }
 }

这将失败并显示“重新分配给val”消息。 这是因为aName这里只是一个函数(构造函数)参数,并且所有参数都是不可变的,你不能分配它们。

此外,如果您尝试new Person2("foo").aName,它也会失败,因为aName不是Person2的成员。

现在,问你的问题。与java不同,scala中的方法与变量位于同一名称空间中,因此您不能同时拥有变量和具有相同名称的方法。这就是你得到的编译错误的情况。

当你编写class Person2(val name: String)时,得到的是在生成的JVM类中定义的私有最终变量name,它不能在scala中直接访问,方法name(),回报就是价值。

当您编写class Person2(var name: String)时,您再次获得一个私有(非最终)JVNM类成员,以及两个scala方法来访问其值。

因此,您提到的cookbook中的“访问器方法”是指访问底层JVM类的成员的值,而不是正在定义的实际scala类。

最后,当您执行class Person2(name: String)时,您根本没有创建该类的任何成员,因此无法访问。

答案 1 :(得分:0)

Scala编译器在这里与函数和类参数的名称相混淆。这个例子有效:

scala> class Person2(aName : String) {
     | def name = aName
     | def name_=(name : String) {aName = name}
     | }
defined class Person2