我遇到了一个问题,研究 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”部分的(新)定义。
我的困境似乎是:如果我只是将方法“dangerous_one”设为私有(private),则没有什么可以阻止 B 类中的客户端代码覆盖它,甚至可能将其公开。
如果我从签名中隐藏它的实现,它就不能再被覆盖,但我不能再调用“b#dangerous_one” - 代码也变得无法调用。
有什么办法可以实现我的目标吗?
最好, 纳 bool 曾
最佳答案
If I hide its implementation from the signature, it can not be overwritten anymore, but I cannot call "b#dangerous_one" anymore - the code becomes inaccessible to calls also.
可以,只需将其设为私有(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 中,您拥有一流的函数、记录、结构等。因此,最好针对每种情况使用合适的工具。当你设计一个类时,你应该明白,方法的原始定义(没有被 C++/Java/Python/etc 破坏)是可以重写的。方法是一种操作,其实现在某些属中有所不同。因此,如果您将某些东西定义为一种方法,然后努力阻止人们覆盖它,那么您很可能做错了什么。如果您不希望它被重写,那么就根本不要将其定义为方法。在您的情况下,您应该将 dangerous_one
操作放入 let 绑定(bind)函数中。您可以将其绑定(bind)在类的上下文中,以便您可以访问所有参数,也可以将其绑定(bind)在顶层,选择权在于您:
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 。虽然有点过时,但仍然非常好。
关于oop - OCaml封装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36423626/