如何强制子类在Ruby中实现方法。 Ruby中似乎没有抽象关键字,这是我在Java中采用的方法。是否还有另外一种类似Ruby的方法来强制抽象?Ruby中的抽象方法
回答
在Ruby中,抽象方法应该不太有用,因为它不是
强烈的
静态类型。
然而,这是我做的:
class AbstractThing
MESS = "SYSTEM ERROR: method missing"
def method_one; raise MESS; end
def method_two; raise MESS; end
end
class ConcreteThing < AbstractThing
def method_one
puts "hi"
end
end
a = ConcreteThing.new
a.method_two # -> raises error.
它很少似乎是必要的,但是。
Ruby是强类型的。只是不是静态类型。 –
我总是弄错了。 Ta,编辑。 – Andy
+1,这就是在Smalltalk中通过'subclassResponsibility'('^ self subclassResponsibility')完成的。 –
我的首选的方法是类似的,但略有不同......我喜欢它,如下所示,因为它使代码自我记录,让您非常相似Smalltalk的东西:
class AbstractThing
def method_one; raise "SubclassResponsibility" ; end
def method_two; raise "SubclassResponsibility" ; end
def non_abstract_method; method_one || method_two ; end
end
有些人会抱怨这是少干,并坚持创建一个异常子类和/或把"SubclassResponsibility"
字符串在一个常量,但恕我直言you can dry things up to the point of being chafed, and that is not usually a good thing。例如。如果您的代码库中有多个抽象类,那么您将在何处定义MESS
字符串常量?!?
我喜欢像abstract_method使用的宝石。这给DSL铁轨样式语法抽象方法:
class AbstractClass
abstract_method :foo
end
class AbstractModule
abstract_method :bar
end
class ConcreteClass < AbstractClass
def foo
42
end
end
我喜欢pvandenberk答案,但如下我会改进:
module Canine # in Ruby, abstract classes are known as modules
def bark
fail NotImplementedError, "A canine class must be able to #bark!"
end
end
现在,如果您创建了一个属于Canine
“抽象类”(即在其祖先中具有Canine
模块的类)的类,它将在发现#bark
方法未实现时发出投诉:
class Dog
include Canine # make dog belong to Canine "abstract class"
end
Dog.new.bark # complains about #bark not being implemented
class Dog
def bark; "Bow wow!" end
end
# Now it's OK:
Dog.new.bark #=> "Bow wow!"
注意,因为Ruby类不是静态的,而是一直开到变化,Dog
类本身不能强制执行的#bark
方法存在,因为当它应该是完成了它不知道。如果你是一名程序员,那么在这个时候你需要测试它。
如果未在继承的类中定义方法'foo','bar'和'mate',则此代码不会让您加载该类。
它没有考虑跨许多文件定义的类,但让我们诚实地做我们中的许多人实际上跨许多文件定义类方法?我的意思是如果你不计算混插。 (此可说明)
def self.abstract(*methods_array)
@@must_abstract ||= []
@@must_abstract = Array(methods_array)
end
def self.inherited(child)
trace = TracePoint.new(:end) do |tp|
if tp.self == child #modules also trace end we only care about the class end
trace.disable
missing = (Array(@@must_abstract) - child.instance_methods(false))
raise NotImplementedError, "#{child} must implement the following method(s) #{missing}" if missing.present?
end
end
trace.enable
end
abstract :foo
abstract :bar, :mate
如果你想在创建类的实例,你可以做以下
class AnstractClass
def self.new(args)
instance = allocate # make memory space for a new object
instance.send(:default_initialize, args)
instance.send(:initialize, args)
instance
end
#This is called whenever object created, regardless of whether 'initialize' is overridden
def default_initialize(args)
self.abstract_method #This will raise error upon object creation
end
private :default_initialize
def initialize(args)
# This can be overridden by new class
end
end
class NewClass < AbstractClass
end
NewClass.new #Throw error
- 1. 抽象方法重写抽象方法
- 2. 建议从抽象类中的方法调用抽象方法
- 3. C#:抽象类中的抽象和非抽象方法?
- 4. c中的抽象方法#
- 5. 抽象方法
- 6. 抽象方法
- 7. Pascal对象中的抽象方法
- 8. 抽象类没有抽象方法
- 9. C#抽象方法
- 10. 抽象类的抽象方法与java中接口的抽象方法的区别
- 11. 可选的抽象方法
- 12. NSURLProtocol的抽象方法
- 13. 如何使用抽象方法测试抽象类中的方法?
- 14. C++:用抽象方法创建抽象类并重写子类中的方法
- 15. 非抽象类不能覆盖Comparable中的抽象方法compareTo?
- 16. 从抽象类中的回调调用抽象方法
- 17. 类不抽象,也不重写java.util.timertask中的抽象方法run()
- 18. 不能实现抽象方法和抽象的说法
- 19. collections.abc中抽象方法的用途
- 20. 抽象类中的泛型方法
- 21. 继承PHP中的抽象方法
- 22. 抽象类(C#)中的部分方法
- 23. typecript mixins中的抽象方法
- 24. 抽象类中的空方法
- 25. 命名空间中的抽象方法
- 26. 虚拟类中的抽象方法
- 27. 编号分类中的抽象方法
- 28. 抽象类中的具体方法
- 29. Eclipse在抽象类中添加抽象方法
- 30. 在抽象类中调用非抽象类方法
另外有一个错误抛出,红宝石使用一种叫鸭打字: http://en.wikipedia.org/wiki/Duck_typing – mikeycgto
@delnan,没有必要像这样说出你的答案。如果我试图坚持Java思维模式,我不会要求“类似Ruby”的解决方案。然而,感谢您对运行时异常的建议。 –
如果我粗鲁无礼,我很抱歉。我刚刚看到*如此多*的人试图用语言A进行编程,就好像它是语言B一样。你问的问题看起来有点像这样,因为你问如何做Java中的抽象类(而不是“等价于抽象类的ruby”或类似于zhsz的东西)。再一次,没有冒犯的意思,也许我错了。 – delnan