ruby - 为什么不能将类用作模块?

标签 ruby class module superclass

ModuleClass 的父类(super class):

Class.superclass
# => Module

在 OOP 中,这意味着 Class 的实例可以用在每个可以使用 Module 实例的地方。

令人惊讶的是,Ruby 中的 Class 实例并非如此:

class C end
c = C.new

module M end
# Let's do all the extend/include/prepend stuff with M!
c.extend M
C.include M
C.prepend M

# All worked fine until this line.
# Let's turn to classes now!

# First, get a class to work with.
class C_as_M end
C_as_M.class.superclass
# => Module # yes, C_as_M is an instance of a Module child
C_as_M.is_a? Module
# => true   # yes, it is still a Module

# And now let's do the same extend/include/prepend stuff with C_as_M!

c.extend C_as_M
# => TypeError: wrong argument type Class (expected Module)
C.include C_as_M
# => TypeError: wrong argument type Class (expected Module)
C.prepend C_as_M
# => TypeError: wrong argument type Class (expected Module)

违反这个OOP原则的原因是什么?为什么不能将类用作模块?

最佳答案

In OOP, this implies that an instance of Class can be used in every place where an instance of Module can be used.

您混淆了子类型和子,即子类型化(关于契约的细化)和继承(关于差异代码重用)。

在 Ruby 中,继承创建了一个子类,但不是子类型。 (其实“类型”在Ruby中是一个只存在于程序员头脑中的概念。)

Class < Module是不是子类型的子类的一个例子,StringIO <:IO是不是子类的子类型的示例。

What is the reason for the violation of this OOP principle?

这不是 OO 原则。子类型和 OO 是完全正交的。有没有子类型的 OO 语言和有子类型的非 OO 语言。


注意:将模块和类合二为一实际上很容易。它们可以像类从类继承以及类从模块继承的方式一样相互继承。

关于ruby - 为什么不能将类用作模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53449705/

相关文章:

module - Yii - 在 Yii 用户模块中使用备用 View 文件

Javascript 对象在赋值后丢失属性

Ruby:如果为真或则获取值

python - 在没有冗余代码/文档字符串的情况下转发/重定向 python 类中的方法/属性的最佳方法?

php - 获取扩展类的文件名

C++:在头文件中包含类定义

ruby-on-rails - 如何使用 Enumerize 验证数组的存在?

ruby - 安装的 Ruby 1.9.3 破坏了我的程序

ruby - 在 ruby​​ 1.9.3. 中,: object-instance. 克隆创建的对象怎么找不到原始对象可以找到的方法?

python 包已安装但无法导入