2016-06-07 49 views
2

是否有一种语言允许超类型A定义了一个方法useFoo(Foo foo),例如B,派生自A定义了一个方法useFoo(Bar bar),(Bar源自Foo),当使用B作为A时, Foo这是一个Bar,它会运行useFoo的最专业版本?是否有一种语言允许动态绑定参数?

Java示例(不工作,不幸):

public class Foo { 

} 

public class Bar extends Foo { 

} 


public class A { 
    void useFoo (Foo foo) { 
     System.out.println("A"); 
    } 
} 

public class B extends A { 
    void useFoo (Bar bar) { 
     System.out.println("B"); 
    } 
} 

public static void main(String[] args) { 
    A b = new B(); 
    b.useFoo(new Bar()); // actually returns "A", is there one returning "B" ? 
} 

我知道有一种方法可以做到这一点与“几”线(例如使用访问者),但我想知道,如果任何(编译的)语言都会允许它。

我承认我想知道这是否甚至可能,相反,我不会感到惊讶,什么阻止它?

这个概念有更好的名字吗?

编辑:在java中,它被命名为逆变。谢谢@Kevinrob

+1

在Java中,它是“协方差”和“逆变”,[见更多](http://stackoverflow.com/a/2501513/244702)。 –

回答

1

你的问题涉及到以下概念:

  1. Covariance:参数可以在子类中重新定义为原来的参数类的子类。例如,该惯例用于艾菲尔。已知该方法导致类型安全问题,CAT-呼叫(CAT =更改可用性或类型),需要以特殊方式解决这一问题以保持类型系统的健全性。协变的强有力论据是,它与合同(例如,按合同设计)很好地结合在一起。
  2. Multiple dispatch:方法调用不仅依赖于调用的目标类型,而且还依赖于参数类型。该页面列出了支持这种机制的几种语言。多次调度是处理协方差和逆变的一种方法。但是,在设计依赖机制的方法集以避免在运行时执行意外的方法时,必须小心。
  3. Generic programming:而不是供应商固定参数类型,它们可以由客户端修复。该机制是类型安全的,并且不存在前两者的问题,但它要求客户端明确指定实际的泛型参数,并且如果太多这样的参数,类型声明可能会变得笨拙。现在有很多支持它的语言。
+0

我真的看到#1和#2的重点,但是为什么是#3? 在我看来,如果能够扩展功能性而不必按指数规律编写代码(比方说,访问者必须针对每种可能的情况进行详细说明),那就更好了。 (虽然冒险,看到你的#2)。你认为你可以提供更多的信息吗?让我清楚,我使用这些技术,我只是好奇。 –

+0

@PierreAntoineGuillaume,#3确实有点偏离原始问题,我已经基于我的个人经验添加了它:当需要重用代码,不同的参数和结果类型以及类型安全性时,可以通过以下方式实现:使用泛型类型。例如,你可以用'void useFoo(T foo)'声明'A ',它可以在'B '中安全地重新定义。然后你会写'A b = new B ();'和'b.useFoo(new Bar());'会打印出你想要的''B''。 –

+0

我不认为我会得到更好的答案,因此我关闭了这个问题,但我倾向于认为它可以处理的方式确实提供了一点调整,具体取决于正在使用哪种语言:在C++中,模板特化会无疑提供了这种功能。我坚持与java atm。哦,非常感谢你的洞察力! –

相关问题