首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场

OCaml封装
EN

Stack Overflow用户
提问于 2016-04-05 18:21:24
回答 1查看 452关注 0票数 2

我正面临着一个问题,研究OCaml文档并没有让我找到一个令人满意的解决方案。

下面的代码片段说明了我的问题:

代码语言:javascript
运行
复制
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

EN

回答 1

Stack Overflow用户

发布于 2016-04-05 19:33:57

如果我对签名隐藏了它的实现,它就不能再被覆盖了,但是我不能再调用"b#dangerous_one“--代码也变得不能被调用了。

你可以,你只需要让它成为private,你不能隐藏public方法:

代码语言:javascript
运行
复制
  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)重新发布它:

代码语言:javascript
运行
复制
  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绑定函数中。你可以在类的上下文中绑定它,这样你就可以访问所有的参数,或者你可以把它绑定在一个顶层上,这是你的选择:

代码语言:javascript
运行
复制
  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。它有点过时了,但仍然很好。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36423626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档