Ruby:创建一个不可继承的类方法

bogh5gae  于 2023-10-18  发布在  Ruby
关注(0)|答案(3)|浏览(128)

假设我有一个类:

class Person
  def self.say
    puts "hello"
  end
end

和子类:

class Woman < Person
  end

我希望“say”方法是公共方法,但我不希望它被“Woman”或任何其他子类继承。实现这一目标的正确方法是什么?

  • 我不想覆盖这个方法,因为我不知道未来的子类。
  • 我知道我可以使用像remove_method这样的方法,但我宁愿根本不继承该方法
a0zr77ik

a0zr77ik1#

我想在基类中有一个静态方法,它根据我提供的参数找到一个子类
在其他地方定义静态方法,例如在模块中:

module Person

  class Base
  end

  class Woman < Base
  end

  def self.create(name)
    case name
    when :woman
      Woman.new
    end
  end

end

Person.create(:woman)          # => #<Person::Woman:0x007fe5040619e0>
Person::Woman.create(:woman)   # => undefined method `create' for Person::Woman:Class
yftpprvb

yftpprvb2#

我同意这是一个奇怪的要求。但是如果您坚持的话,您可以为Person创建一个inherited钩子,并手动从子类中删除类方法。

class Person
  def self.say
    puts "Hello"
  end

  def self.inherited(subclass)
    self.methods(false).each do |m|
      subclass.instance_eval { eval("undef :#{m}") }
    end
  end
end

class Woman < Person
end

Person.say   #=> Hello
Woman.say    #=> undefined method `say' for Woman:Class (NoMethodError)
ukdjmx9f

ukdjmx9f3#

您可以检查类方法调用是来自父类还是来自继承类,然后为其执行适当的逻辑。

class Person 
  def self.say 
    if self.superclass != Person
      puts "Hello"
    else
      puts "Don't say 'hello', make up your own greeting"
    end
  end
end

class Woman < Person 
end

puts Person.say
puts Woman.say

此解决方案满足您的两个要求。

相关问题