我试图找出如何防止所有子类中的一个方法的继承。目前我正在尝试使用这样的代码:
class Mother
def phone
puts "#{self.class} phoned"
end
protected
def phone_kids
puts "phoned kids"
end
end
class Kid < Mother
end
但是没有任何结果,因为我收到了这样的错误:<top (required)>': protected method 'phone_kids' called for #<Mother:0x604da0> (NoMethodError)
。能否简要解释一下Ruby中的继承是如何工作的?
提前致谢!
//编辑:
我使用此代码收到此错误:
kid = Kid.new
mom = Mother.new
mom.phone_kids
答案 0 :(得分:10)
如果您发现自己需要这样做,则可能意味着您没有正确使用继承。如果 C 类继承自 D ,那么它应该是一个“是一个”关系:每个 C 都是 D 。既然不是每个孩子都是母亲,那么在这种情况下使用遗产是不好的。
以下是如何使用单个类代表Ruby中的父母和孩子:
class Person
attr_accessor :name
attr_accessor :children
def initialize(name)
@name = name
@children = []
end
def phone_kids
@children.each { |c| c.phone }
end
def phone
puts "#{@name} phoned"
end
end
现在,回答原来的问题。如果您想阻止Kid
类继承phone_kids
方法,您可以执行以下操作:
class Mother
def self.inherited(klass)
klass.send(:define_method, :phone_kids) do
raise NoMethodError
end
end
def phone_kids
puts "phoned kids"
end
end
class Kid < Mother
end
Mother.new.phone_kids # => phoned kids
Kid.new.phone_kids # => NoMethodError
答案 1 :(得分:1)
在ruby中,private和protected方法都只能在def类中使用。因此,您无法在外部调用受保护或私有方法:
class Mother
def phone
puts "#{self.class} phoned"
end
protected
def phone_kids
puts "phoned kids"
end
private
def anoter_phnoe_kids
puts "anoter phoned kids"
end
end
class Kid < Mother
def hey
phone_kids
anoter_phnoe_kids
end
end
Kid.new.phone #OK
Kid.new.phone_kids #protected method (NoMethodError)
Kid.new.anoter_phnoe_kids #private method (NoMethodError)
Kid.new.hey #OK
here显示protected
和private
之间的差异。
答案 2 :(得分:1)
受保护和私密之间的区别是微妙的。如果方法受到保护,则可以由定义类或其子类的任何实例调用它。如果一个方法是私有的,那么它只能在调用对象的上下文中调用---它永远不可能直接访问另一个对象实例的私有方法,即使该对象与调用者属于同一个类。对于受保护的方法,可以从同一类(或子类)的对象访问它们.`
来源:http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classes#Declaring_Visibility