Inheritance 是否存在方法参数为反变的具有继承的静态类型编程语言?

Inheritance 是否存在方法参数为反变的具有继承的静态类型编程语言?,inheritance,language-agnostic,types,contravariance,Inheritance,Language Agnostic,Types,Contravariance,理论上,用一个方法覆盖子类中父类的方法是合理的,其中参数是父类中参数的超类型,如: class T def foo(s: String) = ... class S override def foo(a: Any) = ... 哪些编程语言支持此“功能”,以及它们如何解决子类的单个方法可以覆盖父类的多个方法的可能性等问题: class T def foo(s: String) = ... def foo(i: Int) = ... class S override

理论上,用一个方法覆盖子类中父类的方法是合理的,其中参数是父类中参数的超类型,如:

class T
  def foo(s: String) = ...

class S
  override def foo(a: Any) = ...
哪些编程语言支持此“功能”,以及它们如何解决子类的单个方法可以覆盖父类的多个方法的可能性等问题:

class T
  def foo(s: String) = ...
  def foo(i: Int)    = ...

class S
  override def foo(a: Any) = ...

(假设
Any
String
Int
子类型)

虽然我掌握了概念,但我不知道是否完全理解您的问题。也就是说,听起来像是说派生类应该能够实现对使用“较少”派生参数的方法的重写。对我来说,这似乎是倒退。重写方法似乎只能使用“更多”派生类型。也许这就是你的意思,也许我弄错了,但这里引用了C#4.0所允许的:

(摘自)

泛型类型参数的方差是多少? 这是C#4.0中的一个新特性。现在,在创建泛型接口时,可以指定在具有不同类型参数的接口实例之间是否存在隐式转换。例如,您可以使用一个接口实例,该接口实例的方法的派生返回类型比最初指定的多(协方差),或者该接口实例的方法的派生参数类型少(反方差)。同样的规则也适用于泛型委托。

(不完整答案)如果我们以OCaml为例,它回答了您问题的标题:这是一种“带有继承的静态类型编程语言,其中方法参数是逆变的”


至于你问题的第二部分(“他们是如何解决诸如……”之类的问题的”),不允许超载可以解决棘手的问题。(重载意味着有两个名称相同但参数类型不同的函数,这使得类型推断更加困难)。

如果你说的是静态类型语言,我不知道。动态类型语言不关心这个问题,所以我假设您讨论的是静态类型语言。请在你的问题中注意这一点。WIkipedia声称一种叫做“Sather”的语言有反变项(,),但我不能保证它的准确性。我不知道这种语言,但我认为一个方法可以从超类重写多个方法这一事实没有问题。当您执行
sInstance.foo(anyObject)
时,将调用此方法。不是
T.foo(字符串)
也不是
T.foo(Int)
。编译器没有问题。只是作为一名程序员,你必须设计你的类,这样这个调用才有意义,“在我看来这是倒退的”——它不是,它是正确的。如果基类中的函数
foo
可以接受任何字符串,则重写
foo
必须至少接受任何字符串,否则它会破坏LSP。另外,矛盾的作用是允许它接受其他事物。使用超级类型的字符串可以做到这一点,它允许使用字符串和其他东西。这是返回类型协方差的另一面,也就是说,如果基类承诺返回字符串,那么派生类可以更具体地返回什么,并且只生成某些子类型的字符串。啊,我发现我没有正确地阅读我自己的引用。我明白了,这正是它现在所说的。