Scala:调用超类构造函数

6
我在经历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")

the execution of

c.getContent

首先打印出“x”(提供给子类构造函数的值),但返回“xXXX”(提供给超类构造函数的值)。
有没有办法避免这种行为?基本上我想要的是子类不创建自己的属性,而是将参数传递给超类。
1个回答

8
它正在按照你告诉它的方式执行。你在传递给超类构造函数时增加了第二个构造函数参数,然后使用了超类的getContent来提供从子类的getContent返回的值。
你需要注意的是,构造函数参数(那些不与属性绑定的参数,因为它们是case class的一部分或者因为它们是用val关键字声明的)在整个类体中都是可见的。类的构造函数是在其方法之外的部分。因此,在方法体中引用构造函数参数会强制将构造函数参数存储在字段中,以便具有必要的范围。请注意,在本例中,getContent中的println调用会导致这种隐藏的构造函数参数字段。
回复评论"是否有另一种定义方式可以避免这种情况?或者至少,如果我从不引用子类构造函数的参数,它们的字段将被分配(浪费内存)?":
如果对普通构造函数参数(*)的唯一引用是在构造函数本身(即在任何方法体之外,并且valvar初始化程序不符合方法体),则不会创建任何隐式字段来保存构造函数参数。
但是,如果你想要避免的不仅仅是这些隐式字段,那么我就不明白你在问什么。
(*)通过"普通构造函数参数",我指的是那些不是case class的一部分,并且没有带有val关键字的参数。

这不是一个案例类,但问题仍然存在 - 特别是因为“content”在子类的主体中被使用。 - Daniel C. Sobral
有没有其他的定义方式可以避免这种情况?或者至少,如果我从不引用子类构造函数的参数,它们的字段会被分配(浪费内存)吗? - mariosangiorgio
3
SubContent.getContent中,请使用super.content而不是仅使用content - Alexey Romanov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接