我有一个像这样的示例代码:
trait X{
val a=1;
val b=2;
}
case class Y(override val a:Int, override val b:Int) extends X{
def sum(c:Int)=a+b+c
}
case class Z(override val a:Int, override val b:Int) extends X{
def sum(c:Int)=a+b+c+10
}
object Test{
def main(args: Array[String]) {
val z = Z(1, 2)
val y = Y(3, 4)
println (y.sum(5))
MyTest[Z].myprint(z) //error here
}
}
class MyTest[A] {
def myPrint(z: A): Unit =
if (z.isInstanceOf[A]) {
val c = z.asInstanceOf[A]
println(c.sum(4)) //error here
}
}
我要做的是创建一个参数化类MyTest,其函数将打印作为参数传递的类的sum
函数。我收到两个错误:
c.sum()
,因为很明显编译器没有关于可以在A中传递什么类的信息。请注意,如果我将方法myPrint放在Test中,这是一个更好的设计,我还有第二个问题。
这可以解决什么问题?
答案 0 :(得分:3)
你做不到
MyTest[Z].myprint(z)
因为它是一个类,所以你必须首先实例化它
val test = new MyTest[Z]
test.myprint(z)
通知您宣布myPrint
并使用myprint
这是一个不同的标识符......
或者您可以使用通用方法
创建object
object MyTest {
def myPrint[A](z: A): Unit = ???
}
关于另一个问题,如果你想调用sum
告诉编译器myPrint采用具有此方法的类型的参数。例如,你可以把它放在你的特质
trait X {
val a = 1
val b = 2
def sum(c: Int): Int
}
并在子类中实现它
然后您可以将其声明为
def myPrint(x: X): Unit =
println(x.sum(4))
}
我把那里4
作为参数,因为我不知道你真正想要实现的是什么,因为你的代码没有传递任何参数来声明你接受一个Int
另一种声明类型(而不是将sum
添加到X
特征的方法是创建另一个特征
trait Summable {
def sum(c: Int): Int
}
让你的类实现它
case class Y(override val a:Int, override val b:Int) extends X with Summable
然后myPrint
需要接受Summable
而不是X
最后,您可以使用结构类型并声明myPrint
,如下所示
def myPrint(x: { def sum(a: Int): Int }): Unit =
println(x.sum(4))
}
答案 1 :(得分:1)
您可以将Structural Types与Bounds一起使用,它基本上定义了给定类型应该具有哪些方法或属性,以便与您的类一起使用。它的功能与鸭子类型的动态语言非常相似。
这样你的类定义可以重写如下:
class MyTest[A <: { def sum(i: Int): Int }]
由于sum
方法接收到一个参数,myPrint
内的调用也应该通过它。修复一下,代码的工作版本是:
trait X {
val a = 1;
val b = 2;
}
case class Y(override val a: Int, override val b: Int) extends X {
def sum(c: Int) = a + b + c
}
case class Z(override val a: Int, override val b: Int) extends X {
def sum(c: Int) = a + b + c + 10
}
class MyTest[A <: { def sum(i: Int): Int }] {
def myPrint(z: A): Unit =
println(z.sum(0)) // I added a zero just to fix the example
}
object Test {
def main(args: Array[String]) {
val z = Z(1, 2)
val y = Y(3, 4)
println(y.sum(5))
new MyTest[Z]().myPrint(z) //error here
}
}