Ruby类访问子类的受保护方法



我有NodeJs的背景,我是Ruby的新手,如果这个问题是个问题,请原谅。我有三节这样的课。

class Babylon::Metric::Counter < Babylon::Metric
protected
def record
# some code here
end
end
class Babylon::Metric::Gauge < Babylon::Metric
protected
def record
# some code here
end
end

它们的父类是

class Babylon::Metric
class ArgumentError < ArgumentError; end
def initialize name, category, amount
@name = name
@category = category
@amount = amount
end
def self.call name:, category:, amount:
new(name, category, amount).()
end
# What is it doing here exactly is it calling Counter or Gauge record method from here, 
# based on valid method returns true or false?
def call
valid? ? record : notify
rescue => e
begin
raise Babylon::Error, e.inspect
rescue Babylon::Error => e
Babylon::Event.(event: "babylon.error", error: e)
end
end
def valid?
# do validation
end
def notify
# do some stuff 
end
end

我认为调用方法可以反过来调用Counter类和Gauge类的记录方法。如果有效方法返回true,但我不知道它如何调用,因为这些都是受保护的成员?。

如果初始化父类并对其调用callrecord方法,则会得到预期的NoMethodError。诀窍是,父母的所有方法都可以在孩子身上使用。

这意味着,如果启动一个子类并对其调用record,则会完全按照预期调用该子类上的记录方法。

但是,如果在子类上调用call方法,它将使用来自父类的实现,但在子类的上下文中,这意味着在其中调用的记录方法将可用,并且不会引发错误。

在Ruby中,protected方法只能用以下任一方法调用:

  • 隐式接收器(即say_hello而非self.say_hello(
  • 同一对象族中的显式接收器(自身和子体(

在父类中,可以看到record是用隐式接收器调用的,这意味着该方法可以是public、protected、private。

例如:

class Foo
def say_hello
whisper_hello # implicit receiver
end
end
class Bar < Foo
private # protected would work as well in this example
def whisper_hello
puts "(hello)"
end
end

在这个例子中,Foo.new.say_hello将失败,因为whisper_hello没有在父类中定义(换句话说,你可以说Foo是一个抽象类(;但是CCD_ 13将正常工作。

最新更新