4

我正在玩方法重新定义,我发现了这个愚蠢的例子:

class a =
object 
    method get (x : a) = x
end

class b =
object
    inherit a
    method get (x : b) = x
end

我明确指定我希望 b 类的 get 方法采用 ab 并返回 ab,但方法签名是 a -> a。如果我这样做 (new b)#get(new a) 他会很高兴,而他真的不应该这样做。之后我添加了一些愚蠢的东西:

class a =
object 
    method get (x : a) = x
end

class b =
object
    inherit a
    method get (x : b) = x#foo(x)
    method foo (x : a) = x
end

我得到Error: This expression has type b It has no method foo

到底发生了什么?

4

1 回答 1

5

首先以第一个例子为例:OCaml 具有对象的结构类型,而不是名义类型。换句话说,对象的类型完全由其方法(及其类型)决定。所以类ab实际上是相同的类型。

$ ocaml
        OCaml version 4.00.0

# class a = object method get (x: a) = x end;;
class a : object method get : a -> a end
# class b = object inherit a method get (x: b) = x end;;
class b : object method get : a -> a end
# let a0 = new a;;
val a0 : a = <obj>
# let b0 = new b;;
val b0 : b = <obj>
# (a0: b);;
- : b = <obj>
# (a0: a);;
- : a = <obj>
# (b0: a);;
- : a = <obj>
# (b0: b);;
- : b = <obj>
# 

(我想在这里展示的是a0andb0都是 typea type b。)

在第二个示例中,我会说您正在尝试为该get方法提供一种新类型。在 OCaml 中重写方法时,参数和返回类型需要与父类中的相同。

错误消息似乎很不幸。我的猜测是编译器相信你 typeb是 type 的另一个名字a

OCaml 的优势之一是它会推断类型。如果您不使用in class的: bfor 参数,则会收到以下错误:getb

This expression has type a. It has no method foo

这更有帮助,因为它表明(我认为)您需要具有a参数的类型。

旁注(原谅我):如果你从主流的 OO 语言来到 OCaml 的 OO 部分,你可能会觉得很奇怪。但是如果你先学习 OCaml 的 FP 部分,你可能想知道为什么所有主流的 OO 语言都会出错:-)。(当然,一切都是权衡,没有一种正确的方法来构建计算。但是 OCaml 的 OO 子系统正在做一些令人印象深刻的事情。)

于 2013-05-23T01:57:16.400 回答