Scala:两个不同类的实例,相同的方法

时间:2011-06-15 08:01:05

标签: generics scala

这是一个微不足道的问题,我只是想知道我是否可以在这里使用Scala-ish。我有两个不同的类(Server1Server2)都实现了一个公共接口/特征(方法.A().B())。

这显然会让编译器感到困惑:

var server = null
if(cond) server=new Server1 else server=new Server2
server.A() //or server.B()

如果我可以使用Scala的选项以一种简洁的方式解决这个问题,我当时很好奇。感谢。

2 个答案:

答案 0 :(得分:8)

始终可以添加类型注释:

var server: TraitOrInterface = null

然而,由于vars有点icky ......

val server = if (cond) {
   new Server1()
} else {
   new Server2()
}

在第二个示例中,Scala应该能够统一类型。 (我相当肯定在某些情况下它无法统一 - 或者它没有按照需要统一,但在回到类型注释之前给它一个镜头,可以按照第一个例子添加。)

REPL演示:

class X
trait Y
class A extends X with Y {}
class B extends X with Y {}
val uni = if (true) new A() else new B()
uni
>> res3: X with Y = A@17b8cf0

快乐的编码。


结构类型示例,type别名是为了方便,但从技术上讲不是必需的。

class Cat { def speak() = "meow" }
class Dog { def speak() = "woof" }
type ThingThatSpeaks = { def speak(): String }

val speaker : ThingThatSpeaks = if (true /* smart */) new Cat() else new Dog()
speaker
>> res4: ThingThatSpeaks = Cat@2893fc
speaker.speak()
>> res5: String = meow

请注意,类型注释是必需的,否则......

val speaker = if (true /* smart */) new Cat() else new Dog()
speaker
>> res6: ScalaObject = Cat@f0ac6e
speaker.speak()
>> error: value speak is not a member of ScalaObject

答案 1 :(得分:1)

不是Option,而是Either

var server = if (cond) Right(new Server1) else Left(new Server2)
server match {
    case Right(srv) => srv.A()
    case Left(srv) => srv.B()
}