2011-06-15 116 views
1

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

这显然混淆编译:

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

我主要是好奇,如果我可以使用Scala的选项来解决这个问题的一种巧妙的方法。谢谢。

回答

8

类型的注释可以随时补充说:

var server: TraitOrInterface = null 

然而,由于瓦尔有点恶心......

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

在第二个例子中,斯卡拉应该能够统一类型。 (我相当肯定,有些情况是无法统一的 - 或者它没有统一到需要的地方,但是在返回到注释类型之前给它一个注释,可以按照第一个例子添加注释。)

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 = [email protected] 

编码愉快。


结构打字例如,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 = [email protected] 
speaker.speak() 
>> res5: String = meow 

注意,被要求类型标注,否则......

val speaker = if (true /* smart */) new Cat() else new Dog() 
speaker 
>> res6: ScalaObject = [email protected] 
speaker.speak() 
>> error: value speak is not a member of ScalaObject 
+0

,如果它不是一个共同的特点,但偶然相同的方法名称? (是的,这是废话 - 但以防万一) – parsa 2011-06-15 08:28:25

+1

@parsa然后你可以使用[结构打字](http://codemonkeyism.com/scala-goodness-structural-typing/):-) – 2011-06-15 08:31:40

+1

@parsa我添加了一个例子利用结构分型。 – 2011-06-15 08:39:50

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() 
} 
相关问题