ruby学习笔记(5)-模块module的运用

ruby中的module与.net中的namespace有点类似,可以用来区分同名但属于不同开发者(或组织)的代码。

下面的代码,定义了一个Me模块,里面的sqrt与Math模块中的sqrt重名,另外还有一个重名常量PI

#定义一个模块(有点类似.net中的命名空间)
module Me
	def sqrt(num1,num2=-1)
		return "num1=#{num1},num2=#{num2}"
	end
	
	PI = 3.14;
end

puts Math::PI #在未include任何模块之前,只能通过完整引用来引用常量
puts Math.sqrt(2) #引用方法用点,引用常量用双冒号

puts "*" * 50 #打印50个*做为分隔线

include Math #包含一个模块(可以理解为c#中的引用命名空间)
puts  sqrt(2) #这里调用的是Math中的sqrt方法

puts "*" * 50
puts Me::PI

include Me
puts  sqrt(2) #这里调用的是Me中的sqrt方法
puts  sqrt(1,2) #同上
puts  PI

puts "*" * 50

puts Math::sqrt(2) #通过完整引用来调用Math中的sqrt方法
puts Math.sqrt(2) #效果与上面相同

puts "*" * 50 

运行结果:

3.14159265358979
1.4142135623731
**************************************************
1.4142135623731
**************************************************
3.14
num1=2,num2=-1
num1=1,num2=2
3.14
**************************************************
1.4142135623731
1.4142135623731
**************************************************

另外模块还能用来实现类似"接口"的效果,比如有这么一个场景:

一个动物游戏中,有N种鸭子,所有的鸭子都会游泳,但野鸭还能飞,按照传统OO的做法,我们会定义一个Duck基类,然后所有鸭子都继承自它,然后再弄一个IFly接口,让“野鸭”类实现该接口即可。

ruby中可以这么干:

#鸭子类
class Duck
	def swim
		print self.class , " can swim...\n";
		end
	end

#"会飞的"模块
module FlyModule
	def fly
		print " and I can fly...\n"
	end
end

#野鸭(会飞,会游)
class Mallard < Duck
	include FlyModule #导入模块后,该类即具有模块中定义的方法(可以理解为实现了接口)
end

#黑鸭(只会游戏)
class Coot < Duck
	def Color
		"Black"
	end
end

aCoot = Coot.new
aCoot.swim;

aMallard = Mallard.new
aMallard.swim;
aMallard.fly;

运行结果:
Coot can swim...
Mallard can swim...
 and I can fly...

最后module还能玩一些静态语言认为BT的东东,比如:刚才这款游戏中,系统随机从天上掉下一个宝贝,一群黑鸭子中谁捡到后谁就能飞起来!这也难不倒ruby:

aCoot1 = Coot.new
aCoot2 = Coot.new
aCoot2.extend(FlyModule)

aCoot1.swim
aCoot2.swim
aCoot2.fly
#aCoot1.fly #因为aCoot1没有扩展FlyModule,所以它不能飞,调用将报错

这里实例aCoot2通过extend关键字,扩展了FlyModule模块,所以这个实例也就能调用FlyModule中的方法!

posted @ 2010-02-11 14:37  菩提树下的杨过  阅读(5357)  评论(0编辑  收藏  举报