【问题标题】:How do I use methods in a namespace that my space's parent's superclass has?如何在我的空间父类的超类拥有的命名空间中使用方法?
【发布时间】:2012-07-31 20:26:31
【问题描述】:

我有一个Book < LibraryItem

还有一个Book::Page,定义为

class Book
  class Page

在models/book/page.rb中

LibraryItem 有一个名为can_edit? 的方法

但是我的Book::Page.new.can_edit? 没有返回任何方法错误...

如何在我的命名空间中包含来自 LibraryItem 的实例方法?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    这会返回错误,因为 Page 没有 can_edit? 方法。 Book 有一个 Page 类,但 Page 不是 Library 项目的子类(只有 Book 是)。所以can_edit?Book 有效,但对Page 无效。

    试试

    p Book::Page.superclass
    

    你会得到Object

    【讨论】:

    • 酷,所以我将其更改为 Book::Page
    • Page 扩展 LibraryItem 是否有意义(我不知道您的 LibraryItem 类的语义)。页面是图书馆项目吗?
    • 好吧,在我的实际代码中,Page 是一个模板,而模板可以独立于我这里的一本书所代表的对象而存在......我应该为 StackOverflow =D 想出一个更好的类比跨度>
    【解决方案2】:

    根本问题是 ruby​​ 不支持多重继承。问题like this onethis one 指出您应该考虑将功能提取到可以任意包含在类定义中的模块中。

    【讨论】:

    • 在这种情况下,我觉得模块在语义上不太正确。
    【解决方案3】:

    如果您在 irb 控制台上运行此代码,Ruby 默认访问父方法:

    class LibraryItem
      def can_edit?
        true
      end
    end
    
    class Book < LibraryItem
      class Page
      end
    end
    

    您可以轻松访问 can_edit 吗?方法,只是做:

    book = Book.new
    book.can_edit?
    

    但是从 Page 类你不能访问 LibraryItem 方法,因为它不在继承链上

    提示:命名空间使用模块而不是嵌套类。

    【讨论】:

    • 最终使两个类都继承自 LibraryItem。这些不是我实际代码中的实际类名,但使用继承更具有语义意义。
    猜你喜欢
    • 2013-01-08
    • 1970-01-01
    • 2021-05-10
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    • 2018-07-02
    • 1970-01-01
    相关资源
    最近更新 更多