防止Ruby中的继承

防止Ruby中的继承,ruby,inheritance,Ruby,Inheritance,我试图找出如何防止在所有子类中继承一个方法。目前我正在尝试使用以下代码: class Mother def phone puts "#{self.class} phoned" end protected def phone_kids puts "phoned kids" end end class Kid < Mother end 如果您发现自己需要这样做,这可能意味着您没有正确地使用继承。如果类C继承自D,那么它应该是一个关系:每个C都是一个D

我试图找出如何防止在所有子类中继承一个方法。目前我正在尝试使用以下代码:

class Mother

  def phone
    puts "#{self.class} phoned"
  end

  protected
  def phone_kids
    puts "phoned kids"
  end
end

class Kid < Mother
end

如果您发现自己需要这样做,这可能意味着您没有正确地使用继承。如果类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

如果您发现自己需要这样做,这可能意味着您没有正确地使用继承。如果类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

在ruby中,私有方法和受保护方法只能在类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

并显示了受保护和私有方法之间的区别。

在ruby中,私有方法和受保护方法只能在类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
并显示了受保护和私有的区别

受保护和私有之间的区别是微妙的。如果一个方法受到保护,它可能会被定义类或其子类的任何实例调用。如果一个方法是私有的,那么只能在调用对象的上下文中调用它——永远不可能直接访问另一个对象实例的私有方法,即使该对象与调用方属于同一类。对于受保护的方法,可以从同一类或子类的对象访问它们`

资料来源:

受保护和私有之间的区别是微妙的。如果一个方法受到保护,它可能会被定义类或其子类的任何实例调用。如果一个方法是私有的,那么只能在调用对象的上下文中调用它——永远不可能直接访问另一个对象实例的私有方法,即使该对象与调用方属于同一类。对于受保护的方法,可以从同一类或子类的对象访问它们`


来源:

您运行什么确切的代码来获取错误消息?为什么孩子从母亲那里继承?孩子是一个特殊类型的母亲吗?你运行什么确切的代码来获取错误消息?为什么孩子从母亲那里继承?孩子是一个特殊的母亲吗?谢谢你的澄清!另一个有趣的提示:如果孩子是母亲的一个子类,那么孩子就是母亲。母亲对任何孩子都是真的,如果孩子是男性,这尤其奇怪。谢谢你的澄清!另一个有趣的提示:如果孩子是母亲的一个子类,那么Kid.is_a?母亲对任何孩子都是真的,如果孩子是男性,这尤其奇怪。