2017-02-07 68 views
1

这是我的问题。Scala提供子类功能的类型信息

我有一个抽象类,它定义了一个类型参数作为输入和输出的方法。我希望子类在子类化时提供类型信息,但我希望以不参数化整个类的方式进行操作。

一些我想要的伪代码。

abstract class A { 
    def foo[T](t: T): T 
} 

class B() extends A { 
    override foo[Int](t: Int): Int = t + 1 
} 

class C() extends A { 
    override foo[Double](t: Double): Double = t + 1.0 
} 

如何传递子类别的类型信息?我看着类似的问题。他们用自我类型,类型类和抽象类型来解决这个问题。

感谢

回答

2

正如你所说的,在A一个抽象类型,可以解决:

abstract class A { 
    type T 
    def foo(t: T): T 
} 

class B extends A { 
    override type T = Int 
    override def foo(t: Int): Int = t + 1 
} 

class C extends A { 
    override type T = Double 
    override def foo(t: Double): Double = t + 1.0 
} 
+0

如果我尝试从外部使用foo函数并将其传递给'foo(t)',其中t被定义为'T <:A',我得到'类型不匹配;预期t.T;实际T' – zaxme

+0

你是什么意思“从外面传递”?您需要在创建'B'和'C'的实例时定义类型。 –

+0

'class D [T <:A] def blah(t:T):T = { t.foo(t) } }' – zaxme

1

什么是 “参数化” 的抽象类:

abstract class A[T] { 
    def foo(t: T): T 
} 

class B extends A[Int] { 
    override def foo(t: Int): Int = t + 1 
} 

class C extends A[Double] { 
    override def foo(t: Double): Double = t + 1.0 
} 
+0

对不起,但正如我所说 - 我不想用类型的原因参数化我的类与稍后的一些子类化。 – zaxme

+0

好吧,够公平的,我错过了(但我没有看到这会如何产生“子类问题”) –

1

A特别有希望的是,它可以用任何T来调用。所以任何扩展它的类型都必须实现这个承诺。

val a: A = ... 
val x = a.foo("a") // calls foo[String] 
val y = a.foo(1) // calls foo[Int] 

是完美的代码。但是当它执行时,a实际上可以是B,C或任何延伸为A的东西。因此,“提供子类化时的类型信息”并没有真正意义:它会完全打破子类型(或类型参数)的含义。