scala用重载方法扩展类



我正在尝试用重载方法扩展类,这样我就可以实例化它并传递不同数量的参数,但保留常见的Foo和Bar类型。如何使我的代码可运行?

class GenericClass {
def run(x: Int): Unit
def run(x: Int, y: Int): Unit
}
class Foo extends GenericClass {
def run(x: Int): Unit
}
class Bar extends GenericClass {
def run(x: Int, y: Int)
}
def getRun(hello: String) = {
hello match {
case "foo" => new Foo
case "bar" => new Bar
}
}
def execIt(runType: String) = {
case "foo" => getRun(runType).run(2)
case "bar" => getRun(runType).run(2, 3)
}
execIt("foo")

您可以尝试引入类型成员

trait GenericClass {
type In
def run(x: In): Unit
}
class Foo extends GenericClass {
override type In = Int
override def run(x: Int): Unit = println("Foo#run")
}
class Bar extends GenericClass {
override type In = (Int, Int)
override def run(x: (Int, Int)): Unit = println("Bar#run")
}
def getRun(hello: String) = {
hello match {
case "foo" => new Foo
case "bar" => new Bar
}
}
def execIt(runType: String) = getRun(runType) match {
case foo: Foo => foo.run(2)
case bar: Bar => bar.run(2, 3)
}
execIt("foo") // Foo#run

或类型类

trait GenericClass
class Foo extends GenericClass
class Bar extends GenericClass
trait Run[A <: GenericClass, T] {
def run(a: A, t: T): Unit
}
object Run {
implicit val foo: Run[Foo, Int] = (a, t) => println("Run.foo")
implicit val bar: Run[Bar, (Int, Int)] = (a, t) => println("Run.bar")
}
implicit class RunOps[A <: GenericClass](val a: A) extends AnyVal {
def run[T](t: T)(implicit r: Run[A, T]): Unit = r.run(a, t)
}
def getRun(hello: String) = {
hello match {
case "foo" => new Foo
case "bar" => new Bar
}
}
def execIt(runType: String) = getRun(runType) match {
case foo: Foo => foo.run(2)
case bar: Bar => bar.run(2, 3)
}
execIt("foo") // Run.foo

请注意,我也修改了execIt

此外,你可以保持一切原样,只需为不需要的方法抛出NotImplementedError

trait GenericClass {
def run(x: Int): Unit
def run(x: Int, y: Int): Unit
}
class Foo extends GenericClass {
def run(x: Int): Unit = println("Foo#run")
def run(x: Int, y: Int): Unit = ???
}
class Bar extends GenericClass {
def run(x: Int): Unit = ???
def run(x: Int, y: Int) = println("Bar#run")
}
def getRun(hello: String) = {
hello match {
case "foo" => new Foo
case "bar" => new Bar
}
}
def execIt(runType: String) = runType match {
case "foo" => getRun(runType).run(2)
case "bar" => getRun(runType).run(2, 3)
}
execIt("foo") // Foo#run

尽管最后一个选项似乎滥用OOP。

最新更新