链式 Scala 特征中 super 的行为
为什么下面的x.func
返回“B extends B extends B”
? 如何安排此代码以使其返回 "B extends A extends Base"
?
trait Base {
def name = "Base"
def func = name
}
trait A extends Base {
override def name = "A"
override def func = name + " extends " + super.func
}
trait B extends Base {
override def name = "B"
override def func = name + " extends " + super.func
}
val x = new Base with A with B
println(x.func)
更新:一种安排可能如下。现在,A
和 B
中的 func1
具有相同的定义。如果我尝试将其移动到 Derived
类,它不起作用。有什么想法如何删除 func1
的重复吗?
trait Base {
def name = "Base"
def func1(s: String) = s
}
trait Derived extends Base {
def func = func1(name)
}
trait A extends Derived {
override def func1(s: String) = s + " extends " + super.func1(super.name)
override def name = "A"
}
trait B extends Derived {
override def func1(s: String) = s + " extends " + super.func1(super.name)
override def name = "B"
}
val x = new Base with A with B
println(x.func)
Why does x.func
below return "B extends B extends B"
?
How to arrange this code so that it returns "B extends A extends Base"
?
trait Base {
def name = "Base"
def func = name
}
trait A extends Base {
override def name = "A"
override def func = name + " extends " + super.func
}
trait B extends Base {
override def name = "B"
override def func = name + " extends " + super.func
}
val x = new Base with A with B
println(x.func)
Update: One arrangement could be as follows. It now has identical definitions of func1
in A
and B
. It does not work if I try to move it to the Derived
class. Any ideas how to remove the repetition of func1
?
trait Base {
def name = "Base"
def func1(s: String) = s
}
trait Derived extends Base {
def func = func1(name)
}
trait A extends Derived {
override def func1(s: String) = s + " extends " + super.func1(super.name)
override def name = "A"
}
trait B extends Derived {
override def func1(s: String) = s + " extends " + super.func1(super.name)
override def name = "B"
}
val x = new Base with A with B
println(x.func)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为继承顺序实际上可能就是您所寻求的。如果将
" extends "
替换为显示调用哪个特征的方法:只是
name
始终为"B"
。换句话说:这就是你想要的......
你的例子的完整线性化是:(
参见http: //ofps.oreilly.com/titles/9780596155957/ScalaObjectSystem.html#Linearization 有关如何计算出的实用说明线性化)
编辑回答评论:为什么
名称
总是返回“B”
?这是因为def name
方法被特征B
覆盖以返回"B"
。这就是继承的全部要点,能够在超类中使用在子类中细化的行为:特征
Legs
中的legs
并不是一个独立于legs< 的行为。
Dog
中的 /code> 取决于您在Legs
或Dog
中引用它...同样,您的def name 将始终返回
"B"
如果您的对象是B
。看起来您想使用 name 作为私有方法:
我发现如果没有清晰的对象模型,使用特征和继承很快就会变得复杂。我假设您清理/简化了示例以使用诸如 A、B、Base、func 之类的通用名称,以便您了解问题的核心,但另一方面,它没有给我任何信息关于您可以进行哪些更改以使其适合您的见解。正如您所问,我已经安排了代码,以便它打印
“B extends A extends Base”
。我确信还有很多其他限制不属于它为什么不适合您的问题。I think the inheritance order may actually be the one your are seeking. If you replace the
" extends "
with one that shows which method of which trait is called:It's just that
name
is always"B"
. In other words:which is what you want...
The full linearization of your example is:
(see http://ofps.oreilly.com/titles/9780596155957/ScalaObjectSystem.html#Linearization for a practical explanation on how to figure out the linearization)
Edit to answer comment: why is the
name
always returns"B"
? That's because thedef name
method is overridden by the traitB
to return"B"
. That's the whole point of inheritance, to be able to use in superclasses behavior that is refined in subclasses:legs
in traitLegs
is not a separate one thanlegs
inDog
depending on if you refer to it inLegs
orDog
... Similarly, yourdef name
will always return"B"
if your object is aB
.It looks like you want to use name as a private method:
I find that if there isn't a clear object model, using trait and inheritance quickly gets complicated. I assume you sanitized/simplified the example to use generic names like
A, B, Base, func
so that you get to the core of the issue, but on the other hand it doesn't give me any insights on what changes you could do to make it work for you. As you asked I've arrange the code so that it prints"B extends A extends Base"
. I'm sure there are a bunch of other constraints that aren't in the question why it won't work for you.