类和模块之间的区别

本文探讨了Ruby中的类与模块的区别。类作为数据类型的蓝图,用于创建对象,支持继承;模块则提供命名空间,防止名称冲突,且实现mixin功能,允许在多个类中复用方法。Ruby的模块类似Java的静态类,不能实例化,而类可以。模块可通过include或extend与其他类结合,实现代码复用和组织。
摘要由CSDN通过智能技术生成

我来自Java,现在我与Ruby进行了更多合作。

module是我不熟悉的一种语言功能。 我想知道module到底是什么,什么时候使用一个module ,为什么要在class使用module


#1楼

基本上,该模块无法实例化。 当类包含模块时,将生成代理超类,该代理超类提供对所有模块方法以及类方法的访问。

一个模块可以包含在多个类中。 模块不能被继承,但是此“ mixin”模型提供了一种有用的“多重继承”类型。 面向对象的纯粹主义者会不同意这种说法,但是不要让纯洁妨碍完成工作。


(此答案最初链接到http://www.rubycentral.com/pickaxe/classes.html ,但是该链接及其域不再有效。)


#2楼

第一个答案是好的,并给出了一些结构性的答案,但是另一种方法是考虑您在做什么。 模块是关于提供可在多个类中使用的方法的-将它们视为“库”(就像在Rails应用程序中看到的那样)。 类是关于对象的。 模块是关于功能的。

例如,身份验证和授权系统就是很好的模块示例。 身份验证系统跨多个应用程序级别的类工作(对用户进行身份验证,会话管理身份验证,许多其他类将根据auth状态而有所不同),因此身份验证系统充当共享API。

在多个应用程序之间共享方法时,也可以使用模块(同样,这里的库模型很好)。


#3楼

Ruby中的Module在某种程度上对应于Java 抽象类 -具有实例方法,类可以从中继承(通过include ,Ruby伙计们称其为“ mixin”),但是没有实例。 还有其他一些细微差别,但是足够多的信息足以帮助您入门。


#4楼

我很惊讶没有人说这个。

由于问问者来自Java背景(我也是),因此有一个类比很有帮助。

类就像Java类一样。

模块就像Java静态类。 考虑一下Java中的Math类。 您没有实例化它,而是重用了静态类中的方法(例如Math.random() )。


#5楼

底线:模块是静态/实用程序类与mixin之间的交叉。

Mixins是可重用的“部分”实现,可以以混合和匹配的方式进行组合(或组成),以帮助编写新的类。 当然,这些类还可以具有自己的状态和/或代码。


#6楼

定义类时,将为数据类型定义一个蓝图。 类保存数据,具有与该数据进行交互并用于实例化对象的方法。

模组

  • 模块是将方法,类和常量分组在一起的一种方式。

  • 模块为您带来两个主要好处:

    =>模块提供名称空间并防止名称冲突。 命名空间有助于避免与其他人编写的具有相同名称的函数和类发生冲突。

    =>模块实现mixin工具。

(包括Klazz中的Module,使Klazz实例可以访问Module方法。)

(用Mod扩展Klazz,使Klazz类可以访问Mods方法。)


#7楼

首先,一些相似之处尚未提及。 Ruby支持开放类,但模块也开放。 毕竟,Class是从Class继承链中的Module继承的,因此Class和Module确实具有某些相似的行为。

但是,您需要问自己:用编程语言同时拥有类和模块的目的是什么? 一个类旨在成为创建实例的蓝图,每个实例都是该蓝图的一个实际变体。 实例只是蓝图(类)的已实现变体。 自然地,类充当对象创建。 此外,由于我们有时希望一个蓝图从另一个蓝图派生,因此类被设计为支持继承。

模块无法实例化,不创建对象,也不支持继承。 因此请记住,一个模块不会从另一个模块继承!

那么,使用某种语言的模块有什么意义呢? Modules的一种明显用法是创建一个名称空间,您也会在其他语言中注意到这一点。 同样,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>

Apple模块没有从Green模块继承任何方法,并且当我们将Apple包含在Fruit类中时,Apple模块的方法被添加到Apple实例的祖先链中,而不是Green模块的方法,即使Green模块在Apple模块中定义。

那么我们如何获得绿色方法? 您必须在班级中明确包含它:

class Fruit
  include Apple::Green
end
 => Fruit 
 > f.green
=> green

但是Ruby还有另一个重要的模块用法。 这是Mixin工具,我在SO的另一个答案中对此进行了描述。 但总而言之,mixin允许您将方法定义到对象的继承链中。 通过mixin,您可以将方法添加到对象实例的继承链(包括)或self的singleton_class(扩展)。


#8楼

名称空间: 模块是名称空间 ...在Java中不存在;)

我也从Java和python切换到了Ruby,我记得有完全相同的问题...

因此,最简单的答案是模块是名称空间,Java中不存在该名称空间。 在Java中,最接近命名空间的是软件包

因此,ruby中的模块类似于java中的模块:
类? 没有
接口? 没有
抽象课? 没有
包? 也许吧)

Java类内部的静态方法:与ruby模块内部的方法相同

在Java中,最小单位是一个类,您不能在一个类之外有一个函数。 但是在ruby中这是可能的(例如python)。

那么模块中包含什么呢?
类,方法,常量。 模块在该名称空间下保护它们。

没有实例:模块不能用于创建实例

混合输入法:有时继承模型不适用于类,但在功能方面希望将一组类/方法/常量组合在一起

红宝石模块规则:
-模块名称为UpperCamelCase
-模块中的常量为ALL CAPS(此规则对于所有ruby常量都是相同的,不特定于模块)
-访问方法:使用。 算子
-访问常量:使用::符号

模块的简单示例:

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文件一个类)


#9楼

╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║               ║ 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)          ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值