Ruby 类实例变量和继承

标签 ruby class instance-variables

我有一个名为 LibraryItem 的 Ruby 类。我想为这个类的每个实例关联一个属性数组。这个数组很长,看起来像

['title', 'authors', 'location', ...]

请注意,这些属性实际上并不是方法,而只是 LibraryItem 具有的属性列表。

接下来,我想创建一个名为 LibraryBookLibraryItem 子类,它有一个属性数组,其中包含 LibraryItem 的所有属性,但是还将包括更多内容。

最终我会想要 LibraryItem 的几个子类,每个子类都有自己的数组 @attributes 版本,但每个都添加到 LibraryItem@attributes(例如,LibraryBookLibraryDVDLibraryMap 等)。

所以,这是我的尝试:

class LibraryItem < Object
  class << self; attr_accessor :attributes; end
  @attributes = ['title', 'authors', 'location',]
end

class LibraryBook < LibraryItem
  @attributes.push('ISBN', 'pages')
end

这是行不通的。我得到错误

undefined method `push' for nil:NilClass

如果它能工作,我想要这样的东西

puts LibraryItem.attributes 
puts LibraryBook.attributes

输出

['title', 'authors', 'location']
['title', 'authors', 'location', 'ISBN', 'pages']

(2010 年 5 月 2 日添加) 一种解决方案是使 @attributes 成为一个简单的实例变量,然后在 initialize 方法中为 LibraryBoot 添加新属性(建议这样做通过 demas 在其中一个答案中)。

虽然这肯定有效(事实上,这也是我一直在做的事情),但我对此并不满意,因为它不是最优的:为什么每次创建对象时都应该构造这些不变的数组?

我真正想要的是拥有可以从父类继承但在子类中更改时不会在父类中更改的类变量。

最佳答案

另一个解决方案是使用inherited 钩子(Hook):

class LibraryItem < Object
  class << self
    attr_accessor :attributes
    def inherit_attributes(attrs)
      @attributes ||= []
      @attributes.concat attrs
    end

    def inherited(sublass)
      sublass.inherit_attributes(@attributes)
    end
  end
  @attributes = ['title', 'authors', 'location',]
end

class LibraryBook < LibraryItem
  @attributes.push('ISBN', 'pages')
end

关于Ruby 类实例变量和继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2752641/

相关文章:

ruby - 全局变量 vs. 常量 vs. 全局缓存的类实例变量

c++ - 指向类数据成员 "::*"的指针

Java:如果这是instanceof Something,则显示仅属于Something的变量?

autohotkey - 为什么我的实例变量在 AHK 中表现得像一个类变量?

objective-c - ivars 必须用大括号括起来吗?

ruby-on-rails - 畸形字符串的 YAML 编码、模型序列化问题

Ruby 的 `respond_to?` 在定义之后不起作用?

ruby - 我应该如何让 Heroku Toolbelt 在 OS X 上使用 2.0.0 而不是系统默认值?

c++ - 如何覆盖继承的嵌套类中存在的虚方法

C++ 对象成员整数具有荒谬的值(value)(WTF)