ruby 同 JAVA 一样只支持单继承,每个类只能有一个父类,为了提高程序的灵活性 ruby 引入了 模块 为实现多重继承提供了可能。模块可以说是类的一个补充,但是模块于类有两个不同:
module 模块名 模块的定义 end
模块名必须是大写字母开头
这个个人理解类似 JAVA 的包,用于对方法,常量,类等名称进行区分及管理。模块提供独立的命名空间,例如模块 A 中的 say_hello 方法和模块 B 中的 say_hello 方法是属于不同的方法。 例子:
module HelloModule
# 定义常量
Version = 'v1.0'
# 定义方法
def say_hello(name)
puts "hello,#{name}"
end
# 指定say_hello 方法为模块函数
module_function :say_hello
end
注释: module_function: 的作用是把方法作为模块函数公开给外部使用,module_function 后面跟的参数是方法名。
Mix-in 就是将模块混合到类中。在定义类时使用 include,从而在类中可以使用模块里的常量、方法等
例子 1:使用关键字 include 使类包含模块 代码:
module Mod
def meth
puts "这是module"
end
end
class ModuleDemo01
include Mod
end
mod = ModuleDemo01.new
mod.meth
输出: 这是 module
如果想校验类是否包含某个模块可以用如下方式: 类名.include?(模块名) 返回 true or false.
1)同继承关系一样,类自身已经定义了同名方法时,优先使用类自身的方法。 例子:
module Mod
def meth
puts "这是module"
end
end
class ModuleDemo01
include Mod
def meth
puts "这个是类的方法"
end
end
mod = ModuleDemo01.new
mod.meth
输出: 这个是类的方法
2)一个类中包含多个模块,优先使用最后一个包含的模块 例子:
module Mod1
def meth
puts "这是Mod1"
end
end
module Mod2
def meth
puts "这是Mod2"
end
end
class ModuleDemo01
include Mod1
include Mod2
end
mod = ModuleDemo01.new
mod.meth
输出:
这是 Mod2
3) 多级嵌套 include 时,查找顺序也是线性的。 例子:
module Mod1
def meth
puts "这是Mod1"
end
end
module Mod2
def meth
puts "这是Mod2"
end
end
module Mod3
include Mod2
end
class ModuleDemo01
include Mod1
include Mod3
end
mod = ModuleDemo01.new
mod.meth
p ModuleDemo01.ancestors
输出: 这是 Mod2 [ModuleDemo01, Mod3, Mod2, Mod1, Object, Kernel, BasicObject]
注释: 通过 类名.ancetores 方法可以查看该类的继承关系和顺序。
4)如果相同模块被包含两次以上(含两次),则第二次后的会被忽略。 例子:
module Mod1
def meth
puts "这是Mod1"
end
end
module Mod2
def meth
puts "这是Mod2"
end
end
module Mod3
include Mod2
include Mod1
include Mod2
end
class ModuleDemo01
include Mod1
include Mod3
end
mod = ModuleDemo01.new
mod.meth
p ModuleDemo01.ancestors
输出:
这是 Mod1 [ModuleDemo01, Mod3, Mod1, Mod2, Object, Kernel, BasicObject]
其实从上面例子就可以看出,一个类可以多个 include 多个模块,并拥有模块的方法,下面这个例子可以更直接看出:
例子:
module Mod1
def meth
puts "这是Mod1"
end
end
module Mod2
def meth
puts "这是Mod2"
end
end
module Mod3
include Mod2
include Mod1
def meth3
puts "这个Mod3的meth3"
end
end
class ModuleDemo01
include Mod1
include Mod3
end
mod = ModuleDemo01.new
mod.meth
mod.meth3
输出: 这是 Mod1 这个 Mod3 的 meth3
参考来源:《ruby 基础教程》