免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5780 | 回复: 7

ruby扫盲之方法的作用域 [复制链接]

论坛徽章:
0
发表于 2010-11-29 12:15 |显示全部楼层
【注】刚才发了一篇,明明提示成功,却没见到帖子。。再发一次。

跟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方法不能被子类继承。

论坛徽章:
0
发表于 2011-02-22 18:57 |显示全部楼层
mark一下。

论坛徽章:
0
发表于 2011-11-19 23:34 |显示全部楼层
呵呵呵呵。学习了。学习了。

论坛徽章:
0
发表于 2012-02-03 19:17 |显示全部楼层
还不熟,呵呵
继续学习,看个明白。

论坛徽章:
0
发表于 2012-02-05 08:06 |显示全部楼层
再复杂的作用域,也比不上JavaScript的作用域啊。

论坛徽章:
0
发表于 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 有何区别?

论坛徽章:
1
天蝎座
日期:2013-08-25 10:27:22
发表于 2012-11-18 22:16 |显示全部楼层
inner_invoke2里很明确是对象自己操作自己的东西。
inner_invoke1不传参数,但是other里虽引用的是自己,但终归是other

论坛徽章:
3
寅虎
日期:2013-11-27 07:53:29申猴
日期:2014-09-12 09:24:152015年迎新春徽章
日期:2015-03-04 09:48:31
发表于 2012-11-19 13:18 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP