我正面临着一个问题,研究OCaml文档并没有让我找到一个令人满意的解决方案。
下面的代码片段说明了我的问题:
class A = object (self)
(* this should not be overwrittable in subclass B, but callable
on objects of type B!
*)
method dangerous_one input =
(do dangerous stuff...)
let safe_output = safe_dangerous_one input in
(... more dangerous things done with safe_output ...)
(* This is safe, should be overwrittable and callable in subclass *)
method safe_dangerous_one input = (...)
end
class B = object(self) inherit A as super
method! safe_dangerous_one input = (* subclass behaviour ... *)
end总结一下代码片段:A类是基类,B类是子类。它有一个危险的方法,它很复杂,而且有一些暗角,我不想让客户机代码去处理。事实上,我想禁止子类重写方法"dangerous_one“。
相反,它们应该覆盖函数"safe_dangerous_one“。
此外,应该可以调用"b#dangerous_one“,其中"b : B”使用类B中指定的"safe_dangerous"-parts的(新)定义。
我的两难境地似乎是:如果我只是简单地将方法"dangerous_one“设为私有,那么没有什么能阻止B类中的客户端代码覆盖它,甚至有可能使它成为公共的。
如果我对签名隐藏了它的实现,它就不能再被覆盖了,但是我不能再调用"b#dangerous_one“--代码也变得不能被调用了。
有没有办法实现我的目标?
最佳,Nablezen
发布于 2016-04-05 19:33:57
如果我对签名隐藏了它的实现,它就不能再被覆盖了,但是我不能再调用"b#dangerous_one“--代码也变得不能被调用了。
你可以,你只需要让它成为private,你不能隐藏public方法:
class type safe = object
method safe_dangerous_one : in_channel -> int
end
class a : safe = object (self)
method private dangerous_one input = input_binary_int input
method safe_dangerous_one input =
max 255 (self#dangerous_one input)
end
class b parameters = object(self)
inherit a parameters as super
method! safe_dangerous_one input =
super#safe_dangerous_one input + 1
end如果您希望unsafe方法是可访问的,但不是可重写的,那么只需以另一个名称(一种NVI)重新发布它:
class type safe = object
method unsafe_dangerous_one : in_channel -> int
method safe_dangerous_one : in_channel -> int
end
class a : safe = object (self)
method private dangerous_one input = input_binary_int input
method unsafe_dangerous_one input = self#dangerous_one input
method safe_dangerous_one input =
max 255 (self#dangerous_one input)
end
class b = object(self)
inherit a as super
method! safe_dangerous_one input =
super#safe_dangerous_one input + 1
end还有一条免费的建议。在其他语言中,类和方法被用作结构化程序的工具,因为它们没有更好的工具。在OCaml中,你有一流的函数、记录、结构等,所以最好在每种情况下都使用合适的工具。当你设计一个类时,你应该明白,method的原始定义(没有被C++/Java/Python/等破坏)是可重写的。方法是一种操作,它的实现在不同的类中是不同的。因此,如果你将某件事定义为一种方法,然后努力防止人们覆盖它,那么你做错了事情的可能性很高。如果你不希望它是可重写的,那么就不要把它定义为一个方法。在您的例子中,您应该将dangerous_one操作放入let绑定函数中。你可以在类的上下文中绑定它,这样你就可以访问所有的参数,或者你可以把它绑定在一个顶层上,这是你的选择:
class a parameters =
let dangerous_one input = input_binary_int input in
object (self)
method safe_dangerous_one input =
max 255 (dangerous_one input)
end
class b = object(self)
inherit a as super
method! safe_dangerous_one input =
super#safe_dangerous_one input + 1
end此外,关于OCaml类系统的一个很好的文档来源是Jason Hickey's Introduction to Objective Caml。它有点过时了,但仍然很好。
https://stackoverflow.com/questions/36423626
复制相似问题