我从Java来了,现在我用Ruby的更多。
一种语言的功能我不熟悉的就是module
。 我想知道究竟是一个module
,当你使用一个,为什么用一个module
在一个class
?
我从Java来了,现在我用Ruby的更多。
一种语言的功能我不熟悉的就是module
。 我想知道究竟是一个module
,当你使用一个,为什么用一个module
在一个class
?
第一个答案是好的,给出了一些结构性的答案,但另一种方法是要想想你在做什么。 模块是关于提供可以跨多个类使用方法 - 想想他们为“库”(你将在Rails应用中看到)。 类是关于对象; 模块是大约功能。
例如,认证和授权系统是模块的很好的例子。 认证系统跨多个应用程序级类工作(用户进行身份验证,会话管理认证,许多其他类会采取不同的基础上,AUTH状态),所以认证系统作为共享的API。
您还可以使用,当你有共同的跨多个应用程序的方法的模块(同样,库模型是好的这里)。
╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║ ║ class ║ module ║
╠═══════════════╬═══════════════════════════╬═════════════════════════════════╣
║ instantiation ║ can be instantiated ║ can *not* be instantiated ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ usage ║ object creation ║ mixin facility. provide ║
║ ║ ║ a namespace. ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ superclass ║ module ║ object ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ methods ║ class methods and ║ module methods and ║
║ ║ instance methods ║ instance methods ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inheritance ║ inherits behaviour and can║ No inheritance ║
║ ║ be base for inheritance ║ ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inclusion ║ cannot be included ║ can be included in classes and ║
║ ║ ║ modules by using the include ║
║ ║ ║ command (includes all ║
║ ║ ║ instance methods as instance ║
║ ║ ║ methods in a class/module) ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ extension ║ can not extend with ║ module can extend instance by ║
║ ║ extend command ║ using extend command (extends ║
║ ║ (only with inheritance) ║ given instance with singleton ║
║ ║ ║ methods from module) ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝
我很惊讶,任何人也没有说这个呢。
由于提问者从Java背景来(所以没有我),这里是一个比喻,帮助。
类是单纯地喜欢Java类。
模块就像Java静态类。 想想Math
中的Java类。 你不实例化,并需要再次使用静态类中的方法(如Math.random()
基本上,模块不能被实例化。 当一个类包括:模块,生成代理超类,提供了访问的所有模块的方法以及类方法。
一个模块可以由多个类被包括在内。 模块不能被继承,但这种“混入”模型提供“多inheritrance”的有用的类型。 OO纯粹主义者会不同意这种说法,但不要让在完成工作的方式获得纯度。
(这个答案原来挂到http://www.rubycentral.com/pickaxe/classes.html
,但该链接,其域名将不再有效。)
Module
在Ruby中,在一定程度上,对应于Java的抽象类 -有实例方法,类可以继承它(通过include
,红宝石人称之为“混入”),但没有实例。 还有其他一些细微的差别,但有一点信息足以让你开始。
底线:一个模块是一个静态/工具类和一个混合之间的交叉。
混入的是“部分”执行可重复使用的作品,可在混搭的方式组合(或组成),以帮助编写新的类。 这些类还可具有自己的状态和/或代码,当然。
命名空间: 模块命名空间 ......不存在于Java中;)
我也是从Java和Python切换到拼音,我记得有完全相同同样的问题...
所以,最简单的答案是,模块是一个空间,它不存在于Java中。 在java中最接近的心态来命名空间是一个包 。
因此,在红宝石模块就像是在java中的内容:
类? 没有
接口? 没有
抽象类? 没有
包? 也许吧)
内部类的静态方法在Java:同内侧红宝石模块的方法
Java中的最小单位是一类,你不能有一类之外的功能。 然而,在红宝石这是可能的(如Python)。
那么进入一个模块?
类,方法,常量。 模块保护他们命名空间下。
没有实例:模块不能被用来创建实例
混合插件:有时遗传模型是不利于类,但在功能方面希望将一组类/方法/常量在一起
关于红宝石模块规则:
- 模块名称是UpperCamelCase
- 模块中的常量都是大写(这条规则是所有红宝石常量一样,不具体到模块)
- 访问方法:使用。 操作者
- 访问常量:使用::符号
一个模块的简单的例子:
module MySampleModule
CONST1 = "some constant"
def self.method_one(arg1)
arg1 + 2
end
end
如何使用模块内部的方法:
puts MySampleModule.method_one(1) # prints: 3
如何使用模块的常量:
puts MySampleModule::CONST1 # prints: some constant
有关模块的其他一些约定:
在文件中使用一个模块(如Ruby类,每ruby文件一个类)
类
当你定义一个类时,你定义数据类型的蓝图。 类的保持数据,有方法,其与该数据交互并用于实例化对象。
模
模块是分组方法,类和常量在一起的一种方式。
模块给你两大好处:
=>模块提供一个名称空间和防止命名冲突。 命名空间有助于避免与函数和类与已经由其他人编写的同名冲突。
=>模块实现混入设施。
(包括在Klazz模块给出Klazz访问模块的方法的实例。)
(与国防部给予MODS的方法的类Klazz访问延伸Klazz。)
首先,一些相似之处还没有被提及。 Ruby支持公开课,但过于模块开放。 毕竟,从类继承模块中的类继承链等类和模块也有一些类似的行为。
但是,你要问自己什么是一种编程语言同时具有A类和模块的目的是什么? 一类旨在是用于创建实例的蓝图,并且每个实例是蓝图的实现变体。 一个实例是仅有的蓝图(类)的实现变体。 当然然后,类作为创建对象。 此外,因为我们有时需要一个蓝图,从另一个蓝图派生,类旨在支持继承。
模块不能被实例化,不创建对象,并且不支持继承。 所以请记住一个模块不从另一个继承!
那么什么才是一个语言模块具有的意义呢? 模块中的一个明显的用途是创建一个命名空间,你会发现这与其他语言了。 再次,什么是酷关于Ruby是模块可以重新打开(就像类)。 这是当你要重复使用在不同的Ruby文件命名空间大的用法:
module Apple
def a
puts 'a'
end
end
module Apple
def b
puts 'b'
end
end
class Fruit
include Apple
end
> f = Fruit.new
=> #<Fruit:0x007fe90c527c98>
> f.a
=> a
> f.b
=> b
但模块之间没有继承:
module Apple
module Green
def green
puts 'green'
end
end
end
class Fruit
include Apple
end
> f = Fruit.new
=> #<Fruit:0x007fe90c462420>
> f.green
NoMethodError: undefined method `green' for #<Fruit:0x007fe90c462420>
苹果模块没有继承从绿色模块的任何方法,当我们在水果类包括苹果,苹果模块的方法添加到苹果实例的祖先链,而不是绿色模块的方法,即使绿模块是苹果的模块中定义。
那么,如何才能获得绿色的方法? 你必须明确地将其包含在类:
class Fruit
include Apple::Green
end
=> Fruit
> f.green
=> green
但是Ruby对模块的另一个重要用途。 这是密新工厂,这是我在另一个答案描述的SO。 但总而言之,混入允许你定义方法为对象的继承链。 通过混入,你可以添加方法,以对象实例(包括)或自我singleton_class的产业链(延伸)。