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 # => #