Ruby 中的抽象方法
如何强制子类实现 Ruby 中的方法。 Ruby 中似乎没有抽象关键字,而我在 Java 中则采用这种方法。还有另一种更像 Ruby 的方式来强制抽象吗?
How can I force a subclass to implement a method in Ruby. There doesn't seem to be an abstract keyword in Ruby, which is the approach I would take in Java. Is there another more Ruby-like way to enforce abstract?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
抽象方法在 Ruby 中应该不太有用,因为它不是
强静态类型。然而,这就是我所做的:
然而,这似乎很少是必要的。
Abstract methods are supposed to be less useful in Ruby because it's not
stronglystatically typed.However, this is what I do:
It rarely seems to be necessary, however.
我喜欢 pvandenberk 的答案,但我会对其进行如下改进:
现在,如果您创建一个属于
Canine
“抽象类”的类(即具有Canine
的类)模块),如果发现#bark
方法未实现,它会抱怨:请注意,由于 Ruby 类不是静态的,而是始终开放更改,
Dog
类本身不能强制存在#bark
方法,因为它不知道什么时候应该完成。如果你作为程序员这样做,那么这个时候就由你来测试它。I like the answer by pvandenberk, but I would improve it as follows:
Now if you make a class belonging to
Canine
"abstract class" (ie. a class that hasCanine
module in its ancestors), it will complain if it is found that#bark
method is not implemented:Note that since Ruby classes are not static, but always open to changes,
Dog
class itself cannot enforce existence of#bark
methods, since it doesn't know when is it supposed to be finished. If you as a programmer do, it is up to you to test it at such time.我喜欢的方法类似,但略有不同...我更喜欢如下,因为它使代码自我记录,为您提供与 Smalltalk 非常相似的东西:
有些人会抱怨这不太 DRY,并坚持创建异常子类和/或将
"SubclassResponsibility"
字符串放入常量中,但恕我直言 你可以把东西弄干到被摩擦的程度,这通常不是一件好事。例如,如果您的代码库中有多个抽象类,那么您将在哪里定义MESS
字符串常量?!?My preferred approach is similar but slightly different... I prefer it as follows, because it makes the code self-documenting, giving you something very similar to Smalltalk:
Some people will complain that this is less DRY, and insist on creating an exception subclass and/or put the
"SubclassResponsibility"
string in a constant, but IMHO you can dry things up to the point of being chafed, and that is not usually a good thing. E.g. if you have multiple abstract classes across your code base, where would you define theMESS
string constant?!?我喜欢使用像 abstract_method 这样的 gem,它提供了 dsl Rails 风格的语法抽象方法:
I like the use of a gem like abstract_method which gives a dsl rails style syntax abstract methods:
如果继承类中未定义方法“foo”、“bar”和“mate”,则此代码将不允许您加载该类。
它没有考虑到跨多个文件定义的类,但老实说,我们中的许多人实际上是否跨多个文件定义了类方法?我的意思是如果你不计算混合。 (这确实说明了这一点)
This code will not let you load the class if the methods 'foo', 'bar' and 'mate' are not defined in the inherited class.
It does not account for classes being defined across many files, but lets get honest do many of us actually define class methods across many files? I mean if you don't count mix-ins. (which this does account for)
如果您想在创建类的实例时抛出错误,您可以执行以下操作
If you want to have an error thrown when you create an instance of the class you could do the following
因为问题是(重点)“如何强制子类在 Ruby 中实现方法”,所以我认为我们可以使用 TDD :D,例如:
rspec 共享示例< /code>
也许
测试比 Abstract 更好
:D ,参考:http://morningcoffee.io/interfaces-in-ruby.htmlBecause the question is (focus on) "How can I force a subclass to implement a method in Ruby", so i think we can use TDD :D, for example:
rspec shared example
Maybe
Tests are better than Abstract
:D , reference: http://morningcoffee.io/interfaces-in-ruby.html