在覆盖方法中返回与子对象相同类型的新对象

时间:2017-06-04 08:04:10

标签: object ocaml

我有一个包含多个子类的虚拟超类。以下是我的情况的一个简单示例:

(*Super class*)
class virtual super = object(self : 'self)
 method virtual generateNewOne : X
end;;

(*Child class one*)
class subOne = object(self)
 inherit super

 method subOneMethod x =
  x+2;

 method generateNewOne =
  let a = new subOne in
  a
 end;;

(*Child class two*)
class subTwo = object(self)
 inherit super

 method subTwoMethod x =
  x+3;

 method generateNewOne =
  let b = new subTwo in
  b
 end;;

我的问题是:

我需要为 X 插入什么作为generateNewOne方法的类型?

我的第一个想法是self类型,但据我尝试它不起作用,因为新对象没有自我类型,但是subOne或subTwo。

2 个答案:

答案 0 :(得分:0)

您可以将X替换为super。在这种情况下,generateNewOne的{​​{1}}也必须返回subOne。这可以通过强制来实现:

super

同样适用于method generateNewOne = let a = new subOne in (a :> super)

如果您真的坚持要subTwo返回generateNewOnesubOne,那么subTwosubOnesubTwo将是不兼容的类型,既不是另一个的子类型。原因是它们具有相互不同的super返回类型(更确切地说,我们不知道generateNewOne本身的返回类型,因为super尚未指定。但我们这样做我们确切地知道,XsupersubOne中的至少一个不兼容。在这种情况下,您不能使用继承,因为继承意味着subTwo的类型保持不变。

答案 1 :(得分:0)

如果您创建subOnesubTwo类,则无法执行此操作,因为它们的任何子类都将从generateNewOne返回错误的类型。但是,只要您不需要进一步子类化,就可以将它们定义为普通对象:

(*Super class*)
class virtual super = object (self : 'self)
 method virtual generateNewOne : 'self
end

let rec subOne () = object (self)
 inherit super
 method subOneMethod x = x + 2
 method generateNewOne = subOne ()
end

let rec subTwo () = object (self)
 inherit super
 method subTwoMethod x = x + 3
 method generateNewOne = subTwo ()
end

另一种可能性是使用“功能对象”语法,因此对象返回自身的副本(可能修改了一些字段)。那么generateNewOne即使对于子类也是正确的,例如

class subTwo = object (self)
 inherit super
 method subTwoMethod x = x + 3
 method generateNewOne = {< >}
end