如何強制子類在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. 抽象方法
- 8. Pascal對象中的抽象方法
- 9. 抽象類非抽象方法調用
- 10. 抽象類和抽象方法
- 11. 抽象類沒有抽象方法
- 12. C++抽象方法
- 13. C#抽象方法
- 14. 抽象類的抽象方法與java中接口的抽象方法的區別
- 15. NSURLProtocol的抽象方法
- 16. 可選的抽象方法
- 17. C++:用抽象方法創建抽象類並重寫子類中的方法
- 18. 如何使用抽象方法測試抽象類中的方法?
- 19. 從抽象類中的回調調用抽象方法
- 20. 類不抽象,也不重寫java.util.timertask中的抽象方法run()
- 21. 非抽象類不能覆蓋Comparable中的抽象方法compareTo?
- 22. 不能實現抽象方法和抽象的說法
- 23. 如果無法創建抽象類的新對象,抽象類中的非抽象方法有什麼意義?
- 24. 虛擬類中的抽象方法
- 25. 命名空間中的抽象方法
- 26. collections.abc中抽象方法的用途
- 27. 飛鏢中的抽象方法
- 28. Python中的抽象方法和mixin
- 29. 抽象類中的具體方法
- 30. Python中的抽象方法體3.5
另外有一個錯誤拋出,紅寶石使用一種叫鴨打字: http://en.wikipedia.org/wiki/Duck_typing – mikeycgto
@delnan,沒有必要像這樣說出你的答案。如果我試圖堅持Java思維模式,我不會要求「類似Ruby」的解決方案。然而,感謝您對運行時異常的建議。 –
如果我粗魯無禮,我很抱歉。我剛剛看到*如此多*的人試圖用語言A進行編程,就好像它是語言B一樣。你問的問題看起來有點像這樣,因爲你問如何做Java中的抽象類(而不是「等價於抽象類的ruby」或類似於zhsz的東西)。再一次,沒有冒犯的意思,也許我錯了。 – delnan