本帖最后由 ZumiKua 于 2013-4-1 02:31 编辑
这教程真坑,尤其是类与方法方面……我就捡重要的讲一下吧
类和函数具体还请参考之前的RGSS2和RGSS1教程
【一些声明】
严格来说,Ruby中没有函数,在Ruby中对所谓函数的叫法是方法(method),这一点可以从一些Module类中的方法名称中得到验证(例如:methods),所以这里我也采用了Ruby的命名习惯。(方法和函数还是有所区别,函数一般无所属类)
【前言】
众所周知的是,啊,可能对这个网站的受众来说也不一定是众所周知,Ruby是一个高度抽象化的语言,她有着可以和Smalltalk相媲美的OOP特性。以上,只是我个人的浮夸而已。所以,类——OOP的核心价值所在,在学习Ruby的道路中是一个重中之重。
【什么是类】
类,表示对现实生活中一类具有共同特征的事物的抽象。比如猫,作为一种生物的统称它代表着一类生物,所以我们可以把它看做一个类,它可以形容所有的猫的通性,比如四个爪子,爱抓毛线球,玩耗子,没事卖卖萌。但是,现在我们并没有真正的猫,还只是个对猫的叙述而已。现在,我自己养了一只猫并给她起名叫喵子,那么,她就是猫的一个实例,根据类对猫这一物种的描述所创造出来的一只活生生的猫,你看得见摸得着,如果在程序中形容的话,它就是是可操作的,它确实在内存中开辟了属于自己的空间,等待着我们对他进行料理处理。
【Ruby中的类】
在Ruby中,类变得更加抽象。现在想象一下,我们要对类这个物体本身也下个定义,类到底是干什么的呢?类就是一个形容别的物体通性的概念,它有着……之类的方法,它可以干……之类的事情,那么,我们现在是不是得到了“类”这个物体的通性?那么,我们可以把“类”也做为一个类看待,前面形容猫的类就是“类”的类的一个实例,它是“类”的特指。举个简单的例子,机床可以制造汽车,那么怎么制造机床呢?制造一个制造机床的机床就行了。
【类的具体实现】
class Cat end nyu = Cat.new
class Cat
end
nyu = Cat.new
以上,即为一个类的生产过程,第一行和第二行定义了一个类,定义一个类的标准语法为:
注意,你所给出的类名会被定义为一个全局常量,而常量通常都是以大写字母开头,在定义类时请万分注意。
第三行,通过点语法调用了 Class类的实例——Cat类(*这里的实例是相对于Class类而言,Cat类被当做实例) 的new实例方法(由实例调用的方法,这里是指类似nyu.miao中的miao方法,其由nyu调用,nyu是Cat类的实例,所以miao是实例方法,Cat类是Class类的实例,所以Cat.new的new是实例方法),建立了一个Cat的实例,nyu,这里,nyu就是我们看得见摸得着的猫,而Cat,就是那个猫的统称。
-Tips
注意,Class类同样还有个类方法new(由类调用,与实例方法相反,如Cat.miao中的miao由类Cat方法调用,所以miao为类方法,类方法和实例方法的定义方式不同),和实例方法new完全不同,请勿混淆。
具体的区分方式为:Class.new调用的为类方法,其他的new均为实例方法。具体原因请结合“类”的类和其实例的关系自行考虑。
觉得自己脑髓不够了么?没关系,还有下一班脑髓地狱列车等着你
【方法与类】
-指摘
在本帖中出现过这样一句话“这样一个方法是在一个新脚本中定义的。。所以不是一个类方法”,首先类方法是指Class Method,可以不经实例化直接调用的方法,定义方式为def self.xxx,而非不“在一个新脚本中定义”即可成为所谓的类方法。一个方法是必须属于一个类的,即使一个方法不属于任何一个类/模块的定义范围,它也会属于Object的一个实例(main),这就跟Ruby的top level environment有关了。
方法是用来描述具体行为的一种抽象方式,比如猫会抓老鼠,那么我们可以给猫类定义一个叫做抓老鼠的方法,这样当我们用猫类来建立实例后就给实例赋予了抓老鼠这一技能。
类似
class Cat def catch_the_rat end end nyu = Cat.new nyu.catch_the_rat
class Cat
def catch_the_rat
end
end
nyu = Cat.new
nyu.catch_the_rat
其他关于方法的用法请参考本帖教程(所谓形参部分还请选择性无视)。在用法方面本帖的实用性堪比嗡嗡祖拉(真抱歉用这么冷僻的梗)
【类与类/模块】
类与类最基本的关系是继承。
在类这一抽象层中, 并不是所有的概念都是并列的,比如,生物分为五个界,然后下面又分界门纲目科属种,这些概念层层递进,同时其共性也在渐渐增多,而这一现象在类中的体现就是——继承。
继承可以让子类继承父类的方法,实例变量等。
继承最大的好处就是可以将父类的共性重用。一个父类不一定只有一个子类,多个子类公用一个父类可以有效降低代码的重复率,更有利于贯彻DRY(do not repeat yourself)精神,有助于降低代码的耦合性,提高代码的可重用性。
范例代码:
class Animal #private def eat puts "eating" end end class Cat < Animal def catch_the_rat eat end end Cat.new.catch_the_rat => eating
class Animal
#private
def eat
puts "eating"
end
end
class Cat < Animal
def catch_the_rat
eat
end
end
Cat.new.catch_the_rat => eating
子类Cat可以完全重用父类的eat方法而不需要自己定义,降低了代码的重复率。
-Tips
private方法不可以被子类调用,如范例代码中将第二行的井号删除,就会报NoMethodError
与C++不同的是,在Ruby中类的继承只能是单继承,摒弃了多继承带来的种种恶果,同时引入了module和mixin(混成)机制,也带来了不输多继承的便利。
关于mixin的语法问题非常简单:
module Tools end class ToolBox include Tools end
module Tools
end
class ToolBox
include Tools
end
即可。这里,我们需要说一下Mixin的实现机制。
实际上,Ruby的Mixin即是用一个匿名类来包装include的module,将其插入到当前类的继承链当中,而且越靠后include的module,距离当前的class就越近,例如:
A是B的子类,A中先后引用了C和D两个模块,那么,实际上A的继承链是这样的:A<D<C<B(先include C,A<C<B,再include D,A<D<C<B)
所以,在进行多模块混成的时候,请合理运用super()(执行父类中同名的方法)
啊,好累,剩下的就看心情补上了……
因本人技术水平有限,所述内容难免有错误疏漏之处,恳请各位读者批评指点,以上,另祝各位能够日益精进。
还有,这就是个马甲而已
参考资料:http://www.ruby-doc.org/core-1.9.3/ |