我正在尝试定义一个使用相应伴随对象的特征,即使用特征的类的componion对象。
例如,我有:
:paste
class Parent {
def callMyCompanion = print(Parent.salute)
}
object Parent {
def salute = "Hello from Parent companion object"
}
class Child extends Parent {
}
object Child {
def salute = "Hello from Child companion object"
}
然后我创建一个父对象:
scala> val p = new Parent()
p: Parent = Parent@1ecf669
scala> p.callMyCompanion
Hello from Parent companion object
但是带着孩子:
scala> val c = new Child()
c: Child = Child@4fd986
scala> c.callMyCompanion
Hello from Parent companion object
我想得到:来自Child伴侣对象的Hello:
我怎样才能实现呢?
- 编辑以澄清
感谢您的回复,但是在这种情况下,callMyCompanion是我创建的一个虚拟方法,只是为了解释自己,我正在尝试重用父方法,而不必在每个实现它的类中重写它...
我到目前为止找到的解决方案是实现一个使用伴侣obejct的实例方法......
答案 0 :(得分:6)
我到目前为止找到的解决方案是添加对类中的伴随对象的引用,以便每个实例变量都可以到达它的类的伴随对象
这样,我只需要覆盖该方法来获取对伴随对象的引用......
要做到这一点,我必须实现ParentCompanion特性...
但我不需要覆盖callMyCompanion或任何其他需要访问伴随对象的方法。
如果我能通过反射获得伴侣对象的引用,这一切都会简单得多......
代码是这样的
:paste
trait ParentCompanion {
def salute: String
}
class Parent {
def callMyCompanion = print(companion.salute)
def companion: ParentCompanion = Parent
}
object Parent extends ParentCompanion {
def salute = "Hello from Parent companion object"
}
class Child extends Parent {
override def companion = Child
}
object Child extends Companion {
def salute = "Hello from Child companion object"
}
答案 1 :(得分:4)
正如我在评论中所写,也许类型类可以帮助你:
trait Greeter[T] {
def salute: Unit
}
object Greeter {
implicit def anyToGreeter[A](x: A) = new {
def salute(implicit greeter: Greeter[A]) = greeter.salute
}
}
class Foo
class Bar extends Foo
implicit object FooGreeter extends Greeter[Foo] {
def salute = println("Hello from FooGreeter.")
}
implicit object BarGreeter extends Greeter[Bar] {
def salute = println("Hello from BarGreeter.")
}
有了这个,我得到以下输出:
scala> import Greeter._
import Greeter._
scala> new Foo().salute
Hello from FooGreeter.
scala> new Bar().salute
Hello from BarGreeter.
答案 2 :(得分:2)
此请求等同于静态覆盖。 scala,AFAIK中不存在这样的事情,但是你可以在Child
中包含一个实例方法覆盖,它会为消息调用它的伴随对象。有些东西告诉我你不想这样做。
答案 3 :(得分:1)
实际访问伴随对象而不知道它是哪一个的主要问题是,你基本上只有一个AnyRef
,这根本不是很有帮助。
另一种方法是使用结构类型。我假设您所有不同的伴侣对象都有一些共同点(例如您在salute
特征中捕获的ParentCompanion
)。然后,您可以执行以下操作:
class Parent {
val companion : {
def salute : String
} = Parent
def foo = println(companion.salute)
}
object Parent {
val salute = "Parent Companion"
}
class Child extends Parent {
override val companion = Child
}
object Child {
val salute = "Child Companion"
}
鉴于此,每个子类都可以覆盖companion
属性以指向其对应的伴随对象,只要它满足Parent
中给出的结构类型(即它必须有{ {1}}在这种情况下)。
然后你可以在你的同伴上调用这个方法,如下所示:
salute