具有参数化功能的Scala动态调度

问题描述:

如何使此代码有效?具有参数化功能的Scala动态调度

据我所知,Scala没有动态调度(类似于Java)。是否有可能以某种方式模拟动态调度?

或者什么是最好的解决方案?

object Tezt { 

    case class SuperClazz() 
    case class SubClazz1() extends SuperClazz 
    case class SubClazz2() extends SuperClazz 

    def method(obj: SubClazz1) = { 
    // stuff 
    } 

    def method(obj: SubClazz2) = { 
    // stuff 
    } 

    def func[T <: SuperClazz](obj: T) = { 
    Tezt.method(obj) // Error: Cannot resolve method reference with such signature 
    } 
} 
+0

java也不会允许这个。你的代码完全错误。 尝试解释你正在试图用文字去做什么。 – Dima

+0

我说的Java也没有。我有一个函数接收一个对象,它是'SuperClazz'的子类,并且有2个方法,每个子类都有onde。我如何知道要找到哪个? – pedrorijo91

+0

假设它被允许。如果你传入一个Subclazz3的实例,那么是什么? – Dima

上实现一个参数的动态调度的标准方法是面向对象的多态性

abstract class SuperClazz() { 
    def method(): ReturnType 
} 
case class SubClazz1() extends SuperClazz { 
    def method() = { 
    // stuff 
    } 
} 
case class SubClazz2() extends SuperClazz { 
    def method() = { 
    // stuff 
    } 
} 

// Alternatively just `def func(obj: SuperClazz) =` in this case 
def func[T <: SuperClazz](obj: T) = 
    obj.method() 

记住,你不能与其他case class延长case class,而且它通常被认为是不好的风格完全可以扩展case class。为了实现这个,你可能需要methodSuperClazz中是抽象的,因此SuperClazz应该是traitabstract class

在阶动态调度另一种常见的方法是模式匹配:

sealed abstract class SuperClazz() 
case class SubClazz1() extends SuperClazz 
case class SubClazz2() extends SuperClazz 

def method(obj: SubClazz1) = { 
    // stuff 
} 

def method(obj: SubClazz2) = { 
    // stuff 
} 

def func(obj: SuperClazz) = 
    obj match { 
    case sc1: SubClazz1 => method(sc1) 
    case sc2: SubClazz2 => method(sc2) 
    } 

这是常见的实现方式类似这样的匹配时,超类或性状sealed(在这种情况下sealed abstract class SuperClazz())。在密封超类的对象上进行匹配时,编译器会检查你是否列出了匹配的所有可能性,以确保匹配时不会出现运行时错误。如果忘记指定一些可能性,编译器会给你一个警告。

模式匹配也适用于多参数动态分派,但与多态性相比,它们通常需要编写更多样板代码,并且可能会有更高的运行时性能成本,以便线性测试每个匹配案例并调用unapply函数。

+0

备注:我无法从另一个案例类扩展案例类?不知道,但我没有得到任何错误。顺便说一句,为什么被认为是不好的做法来扩大案例类? – pedrorijo91

+1

@ pedrorijo91案例类从案例类继承已被禁止自Scala版本2.9。你有没有尝试用这种继承来编译一些代码? IDE可能不会出现错误,但它仍然不会在现代Scala版本中编译。 – Kolmar

+1

@ pedrorijo91至于从案例类继承正常的类,它往往只是没有意义。所有自动案例类方法仍将由父案例类提供。例如,对孩子调用'copy'方法返回父类案例的一个实例。 unoverridden'equals'和'hashCode'只考虑父类案例中存在的字段。对于孩子来说,没有自动伴侣对象使用'apply' /'unapply'。通常的方法是建立一些特征和抽象类的层次结构,并且只在这个继承层次结构中使叶子成为'case class'es。 – Kolmar