Ruby中抽象类的替代方法?

我是Ruby的新手。 一个简单的例子,我需要的:

class Animal abstract eat() class Cat < Animal eat(): implementation class Dog < Animal eat(): implementation 

换句话说,所有扩展Animal的类都需要eat()方法。

在JAVA中,我只使用一个抽象类,但经过一些研究后我发现许多人不在Ruby中使用它,而建议使用mixin / modules。

但是,我不明白,如果模块可以做的不仅仅是包含一个额外的方法。 确切地说,模块是否可以为类必须实现哪些方法设置要求(如果是,可以赞赏一个例子)?

总而言之,在这种情况下我应该使用什么,当我想确定,所有相同类型的类都有特定的方法并以自己的方式实现它们?

Ruby不提供此function,不。 您有责任确保您的类实现他们应该实现的内容。

Ruby不可能实现这样的function的部分原因是Ruby类可以重新打开,Ruby支持在运行时加载任意代码,因此在我们尝试调用它之前,我们无法知道类是否实现了某个接口。

假设Animal必须有eat ,我会做以下事情:

 class Cat < Animal def talk puts "meow" end end class Cat def eat puts "om nom nom" end end 

在该文件的末尾, Cat将具有其eat定义,因为Ruby类可以多次重新打开和修改。 在第一个定义之后代码是否会出错,因为还没有定义eat ? 由于重新开放课程很常见,即使这个例子是人为的,这种实施方式的伤害也会超过它的帮助。 如果调用eat方法并且不存在,它是否应该出错,那么我们可以确定它是在我们需要它时定义的吗? 好吧,如果方法丢失了,那么无论如何都会发生。 解释器永远不会知道另一个类定义是否正在进行中,因此在实际调用该方法之前它永远无法切断。

简而言之,超类根本不可能要求在Ruby中定义方法,因为类的动态性质与这样的目标相矛盾。

抱歉! 不过,这是一个unit testing可能会派上用场的地方,以确保您的子类能够完成他们应该做的事情。

使用定义必须实现的方法的模块。

 module Animal def eat raise NotImplementedError end end class Cat include Animal def eat "Om nom nom" end end class Dog include Animal end c = Cat.new c.eat # => "Om nom nom" d = Dog.new d.eat # => NotImplementedError 

Yo可以使用空方法,或者让它们引发错误以强制子类实现它们。

 class Base def abstract_method end def mandatory_abstract_method raise NotImplementedError.new("You must implement this") end end 

缺点是这只会在实际调用方法时强制执行。 Ruby是一种动态语言,它没有任何编译时检查。

Ruby中没有与抽象类相同的东西。 这主要是因为Ruby是动态类型的,这意味着抽象类的概念并不真正适用。

如果你真的想要实现抽象,那么你使用抽象gem。

 sudo gem install abstraction 

引用来自Abstraction gem WIKI的示例示例。

 class Car abstract def go_forward # ... end end Car.new > AbstractClassError: Car is an abstract class and cannot be instantiated class Convertible < Car def door_count 2 end end class Sedan < Car def door_count 4 end end Convertible.new # => #