从 Ruby 中的实例方法调用继承的 class 方法

Calling inherited class method from instance method in Ruby

我有以下 Ruby 代码:

class B
  class << self
    protected
    def prot
      puts "victory"
    end
  end
end
class C < B
  def self.met
    C.prot
  end
end

C.met

它试图证明受保护的 class 方法是在 Ruby 中继承的。问题是,如果我将 met 方法转换为这样的实例方法:

class B
  class << self
    protected
    def prot
      puts "victory"
    end
  end
end
class C < B
  def met
    C.prot
  end
end

c = C.new
c.met

这是行不通的。也许它与 class 和实例方法范围有关?

不行,因为C的实例不是kind_of?(B.singleton_class)

在 ruby 中,可以在 kind_of? 对象的上下文中调用受保护的方法,class 定义方法,显式接收者也是 kind_of? 定义方法的 class。

您在 B 的单例 class 上定义了一个受保护的方法,因此该方法只能在 kind_of?(B.singleton_class) 的对象中调用。 classC继承了B,所以C的单例class继承了B的单例class,所以Ckind_of? B.singleton_class。因此,在您的第一种情况下,它有效。但是很明显,C.new不是kind_of? B.singleton_class,所以不行。

对于受保护的方法,我们可以从属于同一 class 的任何对象的范围内调用它们。在您的代码片段中,根据 class 的范围,方法查找链选择该方法,因为它继承到超级 class。这意味着,您在其 Singleton class 中定义了一个方法,这意味着我们可以使用该 class 的对象来调用它。因为B对象继承自A,所以我们可以通过A和B的对象来调用它。

简而言之,您可以在 class 的 public 方法中调用受保护的方法。 请参考以下网址以便更好地理解

http://nithinbekal.com/posts/ruby-protected-methods/

accessing protected methods in Ruby

我认为这与将 .protegido 方法声明为元 class(或单例 class)的一部分而不是作为 B 的一部分的区别有关class 本身。

在这里阅读:Metaprogramming in Ruby: It's All About the Self