我有一个名为 LibraryItem
的 Ruby 类。我想为这个类的每个实例关联一个属性数组。这个数组很长,看起来像
['title', 'authors', 'location', ...]
请注意,这些属性实际上并不是方法,而只是 LibraryItem
具有的属性列表。
接下来,我想创建一个名为 LibraryBook
的 LibraryItem
子类,它有一个属性数组,其中包含 LibraryItem
的所有属性,但是还将包括更多内容。
最终我会想要 LibraryItem
的几个子类,每个子类都有自己的数组 @attributes
版本,但每个都添加到 LibraryItem
的@attributes
(例如,LibraryBook
、LibraryDVD
、LibraryMap
等)。
所以,这是我的尝试:
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/