首 页 » 程序开发 » Ruby中实例变量,类变量,类实例变量,类常量的继承分析

Ruby中实例变量,类变量,类实例变量,类常量的继承分析

[ 2014-08-29 20:22 | 浏览次数: 1,538次 | 0条评论 ]

首先需要说明类中定义变量有三个位置:类定义中, 类方法中, 类实例方法中.

这三个位置都是互斥的.

类定义是指在类中但不在类中的任何方法内,相当于C++的头文件中的类定义.

类方法是指在类自己的函数中,相当于C++的类静态函数

类实例方法相当于C++的类的方法

然后介绍一下这三种变量:

class variables: 以这种方式定义@@var,定义位置可以在类中三个位置任意一个地方(建议在类定义中),定义时必须初始化

class instance variable: 以这种方式定义@var,定义位置必须在类定义或类方法中,可以不用定义而直接使用

instance variable: 以这种方式定义@var,定义位置必须在类实例方法中,可以不用定义而直接使用

: 首字母必须大写,且定义时必须赋值, 定义位置可以在类定义中或者在类外,如: C1 = 23(在类中), Class1::C2 = 24(在类外)

1. 实例变量

按照传统语言(如C++语言),当子类继承父类时会继承父类的实例变量,如果有同名则保持两份变量.

Ruby与此不同,ruby其实不继承实例变量,它只继承方法,类变量,类常量等.

Ruby的实例变量只有在函数中遇到才产生.与父类的实例变量没有关系,且属于私有

看如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Class2
	def initialize
		@x = 1
	end
end
 
class Class3 < Class2
	def initialize
		@x = 5 #子类赋值并产生一个实例变量x
		super  #调用父类的同名函数,父类也有一个实例变量x,按照传统语言,
			#父类操作自己的实例变量不影响子类的实例变量,
			#但ruby不是,ruby不管父类或子类,在函数中碰到新的变量就当成自己的实例变量
		puts @x  #所以这里的实例变量被父类的函数操作了,变成了1
	end
end

2. 类实例变量

首先类也是一个对象,因此类实例变量相当于一个对象的实例变量,所以规则与上面的实例变量一样,不继承,在函数中遇到就新建一个类实例变量,与父类的类实例变量没有关系,且属于私有

3. 类变量

这个比较特殊,它会继承,且所有子类中共享这个变量,即一个地方修改了,其他也被修改了,另外如果在父类存在这个类变量,子类就只能共享父类的,不能新建一个同名的.

如果父类动态添加了类变量(无论在什么位置),子类马上就可以用这个新的类变量,弃用自己的.

如果父类动态添加了类变量和子类的已有类变量重名,子类的类变量就引用父类的.

总的来说当ruby碰到一个类变量时,会先在父类中查找(不管自己有没有),找到就用父类的,没找到就新建一个.

这个很好hack喔,只要在全局(这里是所有类的父类)添加一个类变量,按照父类有就用父类的原则,所有的类变量都会使用这个(不管有没有已经创建).这样就可以控制所有类变量了

4. 类常量

类常量可以继承,且继承是引用父类的,即大家是共享的,那个源头重新初始化,所有引用的都会修改.(注意:我这里重点说的是源头,如果不是源头,那就是某个子类重新定义了)

如果父类动态添加了类常量,子类会马上可以引用新的类常量.

看起来好像和类变量相似,但是注意了,子类可以重新定义类常量(即类常量加上赋值语句就是定义了),一旦重新定义就用自己的了,和父类的同名类常量就没有关系了.

注: 类常量没有修改的概念,只有重新初始化

类B继承A

A::C1 = 2 #定义一个常量C1,B也有了这个常量

A::C1 = 3 #重新初始化这个常量C1,B马上引用了新的常量

B::C1 = 4 #注意这里不是修改C1,而是重新为B定义了一个常量C1,所以和A常量的关系就没有了,B自己有了,现在A的常量为3,B的常量为4

总结:

类实例变量和实例变量没有继承,

类变量可以继承,且继承的是引用(父子中任何一个修改,父子也会被修改),子类可以修改父类的.

不能重定义,无论何时整个继承体系都不能有两个同名类变量,且整个继承体系都共享一个类变量.

类常量可以继承,且继承的是引用(父子中任何一个修改,父子也会被修改),子类不能修改父类的.

能重定义,一旦重定义就和父类的没有关系了.

您可以任意转载本文,但转载时请勿删除作者信息。
作者:hgyxbll,原文链接:http://shashanzhao.com/archives/1056.html
上一篇: | 下一篇:

沙发为空,还不快枪?[点此发言]

目前还没有任何评论.