我正在阅读Beginning Ruby并且我在关于私有和受保护方法的部分被困。我知道这是一个新手问题。我搜索了一下SO,但我无法找到一个明确的,新手友好的解释私有和受保护方法之间的区别。
本书给出了两个例子,第一个用于私有方法:
class Person
def initialize(name)
set_name(name)
end
def name
@first_name + ' ' + @last_name
end
private
def set_name(name)
first_name, last_name = name.split(/\s+/)
set_first_name(first_name)
set_last_name(last_name)
end
def set_first_name(name)
@first_name = name
end
def set_last_name(name)
@last_name = name
end
end
在这种情况下,如果我尝试
p = Person.new("Fred Bloggs")
p.set_last_name("Smith")
它会告诉我我不能使用set_last_name方法,因为它是私有的。一直都很好。
但是,在另一个例子中,他们将年龄方法定义为受保护的,当我这样做时
fred = Person.new(34)
chris = Person.new(25)
puts chris.age_difference_with(fred)
puts chris.age
它出错了:
:20: protected method 'age' called for #<Person:0x1e5f28 @age=25> (NoMethodError)
老实说,我没有看到私有方法和受保护方法之间的区别,这听起来和我一样。有人能给我一个明确的解释,所以我再也不会对此感到困惑吗?
如有必要,我会提供第二个例子的代码。
答案 0 :(得分:3)
受保护的方法(或属性)只能由继承带有受保护方法(或属性)的类的类使用。
a d
\ \
b e
\
c
如果a类有受保护的方法,则b和c可以使用它,但d或e不能使用。 注意:在ruby类中继承的Ascii art图。
class A
public
def f obj
obj.c
end
def g obj
obj.b
end
def call_b
b
end
private
def b
puts "Hi!_b"
end
protected
def c
puts "Hi!_c"
end
end
a = A.new
b = A.new
a.f(b) # Hi!_c
a.g(b) # inj.rb:7:in `g': private method `b' called for #<A:0xb76df4cc> (NoMethodError)
a.call_b # Hi!_b
在这种情况下,方法f可以“看到”受保护的方法,因为它具有相同的类(或继承的类),但私有方法封装(隐藏)所有情况的'b'方法,除非这是在他的类中调用的(通过另一个可访问的方法(在这种情况下,方法call_b))。