程序
Ruby类下对访问控制的限制也是用public,protected和private来做的。但是Ruby下的protected和private的使用和java、c++有所区别。
#!/usr/bin/ruby -w
class ClassSuper
attr_accessor :attr1
def initialize
@attr1 = "attr1"
end
private
def privateMethod
puts "this is private"
end
#protected = private which cannot be called directly
protected
def protectedMethod
puts "this is protected"
end
end
class ClassChild < ClassSuper
public
def callProtected
protectedMethod #调用父类protect方法
end
def callPrivate
privateMethod #调用父类private方法
end
def objProtected obj
obj.protectedMethod
end
#this is invalid
def objPrivate obj
obj.privateMethod
end
end
a = ClassChild.new
puts a.attr1 #attr1
a.callProtected #this is protected
#1.以上代码说明隐式调用父类protect方法可以
a.callPrivate #this is private
#2.以上代码说明隐世调用父类私有方法可以!!!!
#a.privateMethod #private method `privateMethod' called for #<ClassChild:0x000000026cb108 @attr1="attr1"> (NoMethodError) Did you mean? private_methods
#3.以上代码说明直接通过子类实例显式的调用父类私有方法不行!!!注意与2对比
# a.protectedMethod #protected method `protectedMethod' called for #<ClassChild:0x00000000d73228 @attr1="attr1"> (NoMethodError) Did you mean? protected_methods
#4.以上代码说明直接通过子类实例显式的调用父类protect方法不行!!!注意与1对比
a.objProtected a #this is protected
#5.以上代码说明直接通过参数传递的方式,显式的调用父类protect方法可以!!!注意与4对比。这个似乎利用了多态。说明protect方法不能被子类显式调用,但是能隐式或者利用多态调用
# a.objPrivate a #private method `privateMethod' called for #<ClassChild:0x000000024375e0 @attr1="attr1"> (NoMethodError) Did you mean? private_methods
#6.以上代码说明直接通过参数传递的方式,显式的调用父类private方法不行!!!注意与2、3对比。说明private方法能被子类访问,但是只能被隐式的调用
结论
Ruby的不同之处在于:
-
private方法能被子类访问,但是只能被隐式的调用。(因为Ruby的原则是“private意为你不能指定方法接收者”,接收者只能是self,且self必须省略!所以Ruby中子类可以访问父类的private方法。)
-
protect方法不能被子类显式调用,但是能隐式或者利用多态调用
-
protected和private的区别是protected能被有条件的显式调用,而private不行