Ruby 新人学 Ruby - Ruby 中的模块

shijin880921 · 2015年09月29日 · 最后由 haroldrandom 回复于 2017年07月14日 · 4830 次阅读

新人学 ruby,有误望提出

模块

模块是什么

ruby 同 JAVA 一样只支持单继承,每个类只能有一个父类,为了提高程序的灵活性 ruby 引入了 模块 为实现多重继承提供了可能。模块可以说是类的一个补充,但是模块于类有两个不同:

  • 模块不能拥有实例
  • 模块不能被继承 --- ## 如何创建模块 ### 关键字:module

语法规则:

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 扩展功能(解决 ruby 单继承)

什么是 Mix-in?

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.

使用 Mix-in 时方法的查找顺序

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]

通过 Mix-in 解决 ruby 单继承问题

其实从上面例子就可以看出,一个类可以多个 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 基础教程》

如果理解了 Ruby 的 ancestors,就不用记住这么多规则了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号