好的,所以我试图在ruby中设置我自己的子类化结构,以允许与Swift中的协议模式匹配的功能。我目前的方法是创建两个基类,一个叫做Protocol,它允许用x个必需方法声明协议,另一个叫做SwiftClass,它允许子类“继承”协议。
协议类
class Protocol
@@required_methods = []
def self.required_method(method_name)
@@required_methods << method_name
end
def self.required_methods
return @@required_methods
end
end
Swift Class
class SwiftClass
@@protocols = []
def self.inherit_protocol(protocol_name)
protocol = Object.const_get(protocol_name)
@@protocols << protocol
end
def self.inherit_protocols(*protocol_names)
protocol_names.each do |protocol_name|
inherit_protocol(protocol_name)
end
end
def self.verify_conforms_to_protocols
@@protocols.each do |protocol|
if protocol.superclass != Protocol
raise "ERROR: #{protocol} must be a subclass of Protocol"
end
if (missing_methods = self.missing_methods_for protocol).length > 0
raise "\nERROR: #{self} does not conform to protocol #{protocol}. \nMISSING METHODS: #{missing_methods.join(", ")}"
end
end
end
def self.missing_methods_for(protocol)
protocol.required_methods.select do |required_method|
!self.method_defined? required_method
end
end
end
然后,我可以创建一个具有所需方法的协议
class SampleProtocol < Protocol
required_method :number_of_sections_in
required_method :number_of_rows_in_section
end
并设置一个类来继承此协议
class SampleClass < SwiftClass
inherit_protocols :SampleProtocol
verify_conforms_to_protocols
end
到目前为止,一切都按照应有的方式运作。如果我运行代码,它会引发我在SwiftClass中设置的错误
ERROR: SampleClass does not conform to protocol SampleProtocol.
MISSING METHODS: number_of_sections_in, number_of_rows_in_section
然后,如果我将方法添加到SampleClass并运行它,它不再引发任何错误:
class SampleClass < SwiftClass
inherit_protocols :SampleProtocol
def number_of_sections_in; end
def number_of_rows_in_section; end
verify_conforms_to_protocols
end
大多数对ruby一无所知的人可能已经看到了这段代码的明显问题;类变量@@ required_methods和@@ protocols都是在超类级别定义的,因此每次我在子类中添加它时,它都会扩展到每个其他子类。例如,如果我在SampleClass声明之前添加一个单独的协议
class SomeOtherProtocol < Protocol
required_method :cell_for_row_at
end
然后运行代码我得到错误
ERROR: SampleClass does not conform to protocol SampleProtocol.
MISSING METHODS: cell_for_row_at
因为@@ required_methods从每个Protocol子类收集所有必需的方法。对于SwiftClass的每个子类,@@ protocols也是如此。
所以我的问题是,我可以使用超类为每个子类设置类变量吗?我希望@@ required_methods变量为Protocol的每个子类保存不同的值,并且@@ protocols变量为SwiftClass的每个子类保存不同的值,但是我仍然希望在超类中保持这个逻辑,这样我就不会必须在每个子类中重复它。
如果可能的话,我想在SwiftClass中保留完全相同的继承协议的结构,这样我就可以设置继承协议的所有“inherit_protocols:SomeProtocol”。使用“method:some_method”调用将方法添加到新协议也是一样。