2010-09-03 169 views
6

我遇到了Scala处理超类构造函数时出现的奇怪行为。Scala:调用超类的构造函数

我有以下方式

package server 

class Content(identifier:String,content:String){ 
    def getIdentifier() : String = {identifier} 
    def getContent() : String = {content} 
} 

和一个简单的子类

package server 

class SubContent(identifier:String, content:String) extends Content(identifier, content+"XXX")){ 

    override def getContent():String = { 
     println(content) 
     super.getContent 
    } 
} 

定义一个非常简单的类,什么是真正奇怪的是,在子类有超类的重复属性,因此如果我创建一个新对象

var c = new SubContent("x","x") 

执行

c.getContent 

第一打印出“X”(该值提供给子类的构造),但返回“XXXX”(该提供给超类构造值)。

有什么办法可以避免这种行为?基本上我想要的是子类不会创建自己的属性,而只是将参数传递给超类。

回答

8

它正在做你刚才告诉它做的事情。在将它传递给超类的构造函数时,扩充了第二个构造函数参数,然后使用超类'getContent提供从子类'getContent返回的值。

你需要知道的事情是,构造函数的参数(那些因为他们是一个case class的一部分,或者因为他们与val关键字声明不依赖于性能)是整个类主体范围。该类的构造函数是它的身体部分以外的任何方法。因此,在方法体中对构造函数参数的引用迫使构造函数参数存储在一个字段中,以便它可以具有必要的范围。请注意,在这种情况下,getContent中的println调用会导致这样一个隐藏的构造函数参数字段。或者至少,如果我从不引用子类构造函数的参数,它们的字段将被分配(浪费内存)?“ :

如果以普通构造函数的参数的唯一引用(*)是在构造适当的(即,任何方法体,和valvar初始化不符合作为法外机构),则没有看不见的领域将创建保存构造函数参数。

但是,如果有更多的人试图“避开”这些看不见的领域,我不明白你在问什么。 (*)通过“纯粹的构造函数参数”我的意思是那些不是一个案例类的一部分,不承载val关键字。

+0

这不是一个案例类,但问题仍然存在 - 特别是因为内容被用在子类的主体中。 – 2010-09-03 18:08:22

+0

是否有其他方法来定义它以避免这种情况?或者至少,如果我从不参考子类构造函数的参数,它们的字段将被分配(浪费内存)? – mariosangiorgio 2010-09-03 18:18:56

+3

在'SubContent.getContent'中使用'super.content'而不是'content'。 – 2010-09-04 11:10:52