zuerrong 发表于 2010-11-29 12:15

ruby扫盲之方法的作用域

【注】刚才发了一篇,明明提示成功,却没见到帖子。。再发一次。

跟java一样,ruby也有public, private, protected三个方法类型。
但是private和protected跟java的稍有不同,总结如下。

irb(main):005:0> class Myclass
irb(main):006:1>   private
irb(main):007:1>   def t1
irb(main):008:2>    "private"
irb(main):009:2>   end
irb(main):010:1>   protected
irb(main):011:1>   def t2
irb(main):012:2>    "protected"
irb(main):013:2>   end
irb(main):014:1> end


上述,定义一个t1私有方法,和一个t2受保护方法。
这两个方法显然都不能直接从外部访问:

irb(main):031:0> x=Myclass.new
=> #<Myclass:0x7f1434f0a3d0>

irb(main):032:0> y=Myclass.new
=> #<Myclass:0x7f1434f060a0>

irb(main):033:0> x.t1
NoMethodError: private method `t1' called for #<Myclass:0x7f1434f0a3d0>
      from (irb):33
      from :0

irb(main):034:0> x.t2
NoMethodError: protected method `t2' called for #<Myclass:0x7f1434f0a3d0>
      from (irb):34
      from :0


但是,受保护方法可以被同一个类的另一个实例访问:

irb(main):026:0* class Myclass
irb(main):027:1>   def t3(a)
irb(main):028:2>   a.t2
irb(main):029:2>   end
irb(main):030:1> end

irb(main):035:0> x.t3(y)
=> "protected"


而私有方法不能被另一实例访问:

irb(main):036:0> class Myclass
irb(main):037:1>   def t4(a)
irb(main):038:2>   a.t1
irb(main):039:2>   end
irb(main):040:1> end
=> nil

irb(main):041:0> x.t4(y)
NoMethodError: private method `t1' called for #<Myclass:0x7f1434f060a0>
      from (irb):38:in `t4'
      from (irb):41
      from :0


私有方法可以被子类访问:

irb(main):049:0> class Mysub < Myclass
irb(main):050:1>   def t5
irb(main):051:2>   t1
irb(main):052:2>   end
irb(main):053:1> end
=> nil

irb(main):054:0> z=Mysub.new
=> #<Mysub:0x7f1434f49300>

irb(main):055:0> z.t5
=> "private"


受保护方法同样可被子类访问:

irb(main):062:0> class Mysub < Myclass
irb(main):063:1>   def t6
irb(main):064:2>   t2
irb(main):065:2>   end
irb(main):066:1> end
=> nil

irb(main):067:0> a=Mysub.new
=> #<Mysub:0x7f1434f11270>

irb(main):068:0> a.t6
=> "protected"



private和protected在ruby和Java里的区别:

1、在不同对象实例当中的作用域不同
Java当中,不管private还是protected的方法,都可以被同一个类别的其他对象实例调用;
Ruby当中,private方法不能被同一个类别的其他对象实例调用。

2、在类继承关系当中的作用域不同
ruby当中,不管private还是protected方法,都可以被子类继承;
Java当中,private方法不能被子类继承。

ziyiu123 发表于 2011-02-22 18:57

mark一下。

gr33n 发表于 2011-11-19 23:34

呵呵呵呵。学习了。学习了。

gr33n 发表于 2012-02-03 19:17

还不熟,呵呵
继续学习,看个明白。

2gua 发表于 2012-02-05 08:06

再复杂的作用域,也比不上JavaScript的作用域啊。

yangyi10 发表于 2012-11-09 13:55

我自己写代码测试了一下,有几个问题,不明缘由,还请指点。

class Soap

def inner_invoke1 (other=self)
    other.pub
    other.pro
    other.pri
end

def inner_invoke2
    pub
    pro
    pri
end

public
def pub
    puts "public"
end

protected
def pro
    puts "protected"
end

private
def pri
    puts "private"
end

end

s1=Soap.new
s1.inner_invoke1 Soap.new         #a
s1.inner_invoke1                  #b
s1.inner_invoke2                  #c


这个作用域的问题我有点看不懂了,当inner_invoke1不传参数的时候,为啥会报错呢?

inner_invoke1 不传参数 和 inner_invoke2 有何区别?

yangsf5 发表于 2012-11-18 22:16

inner_invoke2里很明确是对象自己操作自己的东西。
inner_invoke1不传参数,但是other里虽引用的是自己,但终归是other

Sevk 发表于 2012-11-19 13:18

页: [1]
查看完整版本: ruby扫盲之方法的作用域