scala 通过特征覆盖方法时如何调用超级方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19237049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to call super method when overriding a method through a trait
提问by jedesah
It would appear that it is possible to change the implementation of a method on a class with a trait such as follows:
似乎可以更改具有以下特征的类上的方法的实现:
trait Abstract { self: Result =>
override def userRepr = "abstract"
}
abstract class Result {
def userRepr: String = "wtv"
}
case class ValDefResult(name: String) extends Result {
override def userRepr = name
}
val a = new ValDefResult("asd") with Abstract
a.userRepr
Live code is available here: http://www.scalakata.com/52534e2fe4b0b1a1c4daa436
此处提供实时代码:http: //www.scalakata.com/52534e2fe4b0b1a1c4daa436
But now I would like to call the previous or super implementation of the function such as follows:
但现在我想调用函数的前一个或超级实现,如下所示:
trait Abstract { self: Result =>
override def userRepr = "abstract" + self.userRepr
}
or
或者
trait Abstract { self: Result =>
override def userRepr = "abstract" + super.userRepr
}
However, none of these alternatives compile. Any idea how this could be accomplished?
但是,这些替代方案都无法编译。知道如何做到这一点吗?
采纳答案by jedesah
Here is the answer I was looking for. Thank you Shadowlands for pointing me in the right direction with Scala's abstract overridefeature.
这是我一直在寻找的答案。感谢 Shadowlands 用 Scala 的abstract override特性为我指明了正确的方向。
trait Abstract extends Result {
abstract override def userRepr = "abstract " + super.userRepr
}
abstract class Result {
def userRepr: String = "wtv"
}
case class ValDefResult(name: String) extends Result {
override def userRepr = name
}
val a = new ValDefResult("asd") with Abstract
a.userRepr
Live code is available here: http://www.scalakata.com/52536cc2e4b0b1a1c4daa4a4
此处提供实时代码:http: //www.scalakata.com/52536cc2e4b0b1a1c4daa4a4
Sorry for the confusing example code, I am writing a library that deals with the Scala AST and was not inspired enough to change the names.
抱歉,示例代码令人困惑,我正在编写一个处理 Scala AST 的库,但没有足够的灵感来更改名称。
回答by Shadowlands
I don't know if you are in a position to make the following changes, but the effect you want can be achieved by introducing an extra trait (I'll call it Repr), and using abstract overridein the Abstracttrait:
不知道您是否可以进行以下更改,但是可以通过引入额外的 trait(我称之为Repr)并abstract override在Abstracttrait 中使用来实现您想要的效果:
trait Repr {
def userRepr: String
}
abstract class Result extends Repr {
def userRepr: String = "wtv"
}
case class ValDefResult(name: String) extends Result {
override def userRepr = name
}
trait Abstract extends Repr { self: Result =>
abstract override def userRepr = "abstract-" + super.userRepr // 'super.' works now
}
Your example usage now gives:
您的示例用法现在给出:
scala> val a = new ValDefResult("asd") with Abstract
a: ValDefResult with Abstract = ValDefResult(asd)
scala> a.userRepr
res3: String = abstract-asd
回答by som-snytt
abstract overrideis the mechanism, aka stackable traits. It's worth adding that linearization counts, because that's what determines what supermeans.
abstract override是机制,又名可堆叠特征。值得补充的是,线性化很重要,因为这决定了super意味着什么。
This question is a great addendum to the canonical Q&A on self-type vs extension.
这个问题是关于 self-type vs extension 的规范问答的一个很好的附录。
Where the inheritance is ambiguous with self-types:
继承与自我类型不明确的地方:
scala> trait Bar { def f: String = "bar" }
defined trait Bar
scala> trait Foo { _: Bar => override def f = "foo" }
defined trait Foo
scala> new Foo with Bar { }
<console>:44: error: <$anon: Foo with Bar> inherits conflicting members:
method f in trait Foo of type => String and
method f in trait Bar of type => String
(Note: this can be resolved by declaring an override in <$anon: Foo with Bar>.)
new Foo with Bar { }
^
Then obviously, you can choose:
那么显然,您可以选择:
scala> new Foo with Bar { override def f = super.f }
res5: Foo with Bar = $anon@57a68215
scala> .f
res6: String = bar
scala> new Foo with Bar { override def f = super[Foo].f }
res7: Foo with Bar = $anon@17c40621
scala> .f
res8: String = foo
or
或者
scala> new Bar with Foo {}
res9: Bar with Foo = $anon@374d9299
scala> .f
res10: String = foo

