6.3 实例变量、类变量、类方法

学习编程的过程,就是深化理解变量的过程。在面向对象编程中也不例外,这一节,我们继续深化理解变量。
先把 Ruby 放在一边,从编程语言的视角来探讨变量。
如果一个变量,第一次赋值后,就不再允许改变变量值,这样的变量称之为常变量,简称常量。就像数学分析中的常函数,y = 3 是一个平行于 x 轴,并且函数值总是为 3 的函数。常量名用大写字母开头。
如果一个变量,在其作用域上的每一个执行点,都可以改变变量值,这样的变量称之为可变量,简称变量。
如果一个变量,其作用域遍及在程序的任何位置,这样的变量称之为全局变量;与之相对,作用域仅限于在程序的某一单元的变量,称之为局部变量。
面向对象的编程,以类为单元模块。类是设计蓝图,具体的事物是实例对象。前面 5.3 节说到:“变量名,变量值,变量类型,变量的作用域,是我们学习命令式语言不可回避的几个要素”。对于面向过程的命令式语言,这四个要素已经够了;对于面向对象的命令式语言,还要加上变量的第五个要素——共享性。
如果一个变量,只能被某个实例对象使用,这样的变量称之为实例变量;如果一个变量,能被某个类的所有实例对象共享,这样的变量称之为类变量。
回到 Ruby 。常量可以定义在类和模块中,不能定义在方法中。如果在外部访问类或模块中的常量,要使用域作用符:: 。
全局变量用$ 开头。
实例变量,变量名用@ 开头;类变量,变量名用@@ 开头。
Ruby中所说的局部变量,可以是存在于类中、方法中、模块中、一个循环中、一个过程对象中。局部变量名用小写字母开头。
在4.3节,我们使用的@name(姓名)、@age(年龄)、@motherland(国籍),都是实例变量,被每个实例独享。程序 E4.3-1.rb 中,实例 p1与实例 p2的姓名不一样,年龄也不一样。
如果我们希望一类事物共享某个变量,比如:在 4.4节 Student 类中,需要有一个变量来代表班级人数,实例 p3与实例 p4假使在一个班级里,班级人数这个属性应该是相同的,当然,随着 Student 类的实例不断生成,班级人数也要不断增加,如何解决呢?
类变量能够很好地实现这个需求,看程序 E6.3-1.rb:

#E6.3-1.rb
class StudentClass
@@count=0

def initialize( name )
@name = name
@@count+=1
end

def talk
puts "I am #@name, This class have #@@count students."
end
end

p1=StudentClass.new("Student 1 ")
p2=StudentClass.new("Student 2 ")
p3=StudentClass.new("Student 3 ")
p4=StudentClass.new("Student 4 ")
p3.talk # => I am Student 3 , This class have 4 students.
p4.talk # => I am Student 4 , This class have 4 students.

与全局变量和实例变量不同,类变量在使用前必须要初始化;全局变量和实例变量如果没有初始化,其值为 nil 。
如果教务主任想知道某个班级现在有多少人数,不需要到这个班级去问学生,应该可以通过其它途径来获取信息。这里要用到类方法——不依赖于任何特定实例对象的方法。类方法与实例方法的定义方式不同,定义类方法要在方法名前加上类名和一个点号“.”。看程序 E6.3-2.rb:

#E6.3-2.rb
class StudentClass
@@count=0

def initialize
@@count+=1
end

def StudentClass.student_count
puts "This class have #@@count students."
end
end

p1=StudentClass.new
p2=StudentClass.new
StudentClass.student_count # => This class have 2 students.

p3=StudentClass.new
p4=StudentClass.new
StudentClass.student_count # => This class have 4 students.

调用一个类方法,与定义类方法一样,要在方法名前加上类名和一个点号“.”。类方法提供了一个途径,在类的外部访问类变量,无须通过类的实例方法。
类变量,类方法在 Java 里与之相对应的是 static变量,static方法。
在Java里,你写一个类,是在画设计图纸,当你 new 的时候,才生成一个实例对象。Ruby语言中,一切都是对象,单个实例(具体事物)是对象,类(蓝图)也是对象。你拿着设计图纸可以生产出很多汽车,而设计图纸对于纸来说,只是纸这类事物的一个具体实例。 Ruby里,有元类的概念,通过关键字self 与类方法的灵活使用,程序代码可以产生很多变化,这里不再展开叙述。可以思考用类方法来实现《设计模式》一书中的单子模式。


完整阅读,请看我写的 [url="http://www.iteye.com/topic/47611"]Ruby语言中文教程all in one [/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值