Ruby类的实例变量和继承 [英] Ruby class instance variables and inheritance
问题描述
我有一个Ruby类 LibraryItem
。我想关联这个类的每个实例一个属性数组。这个数组很长,看起来像
['title','authors','location',...] b $ b
请注意,这些属性实际上不是方法,只是属性列表 LibraryItem
有
接下来,我想创建 LibraryItem
调用 LibraryBook
,它有一个包含 LibraryItem
所有属性的属性数组,但也将包括更多。 / p>
最后,我将需要 LibraryItem
的几个子类,每个子类都有自己的数组版本 @属性
,但每个都添加到 LibraryItem
的 @attributes
(例如, LibraryBook
, LibraryDVD
, LibraryMap
等)。
所以,这里是我的尝试:
class LibraryItem< Object
class<<自; attr_accessor:attributes; end
@attributes = ['title','authors','location',]
end
class LibraryBook< LibraryItem
@ attributes.push('ISBN','pages')
end
这不工作。我收到错误
未定义方法`push'for nil:NilClass
pre>
如果是工作,我会想要这样的
puts LibraryItem.attributes
puts LibraryBook.attributes
输出
['title','authors','location']
['title','authors','location' ISBN','pages']
(2010年5月2日添加)
一个解决方案这是为了使@attributes
一个简单的实例变量,然后在<$ c中添加LibraryBoot
的新属性$ c> initialize 方法(这是由demas在其中一个答案中建议的)。
虽然这肯定有效(事实上,我一直在做的),我不满意,因为它是次优的:为什么应该在每次创建对象时构造这些不变的数组?
我真正想要的是具有可以从父类继承的类变量,但在子代中更改时
解决方案由于你提到的属性是固定的和不变的我假设你的意思是,你永远不会改变他们的值一旦对象被创建。在这种情况下,类似以下内容应该工作:
class Foo
ATTRS = ['title','authors ','location']
def attributes
ATTRS
end
end
class Bar< Foo
ATTRS = ['ISBN','pages']
def attributes
super + ATTRS
end
end
您手动实现一个reader方法(而不是让
attr_accessor
为您创建)数组的内部名称。在你的子类中,你只需调用祖先类的reader函数,在与子类相关的附加字段上加上,然后返回给调用者。对用户来说,它看起来像一个名为attributes
的只读成员变量,在子类中具有其他值。I have a Ruby class called
LibraryItem
. I want to associate with every instance of this class an array of attributes. This array is long and looks something like['title', 'authors', 'location', ...]
Note that these attributes are not really supposed to be methods, just a list of attributes that a
LibraryItem
has.Next, I want to make a subclass of
LibraryItem
calledLibraryBook
that has an array of attributes that includes all the attributes ofLibraryItem
but will also include many more.Eventually I will want several subclasses of
LibraryItem
each with their own version of the array@attributes
but each adding on toLibraryItem
's@attributes
(e.g.,LibraryBook
,LibraryDVD
,LibraryMap
, etc.).So, here is my attempt:
class LibraryItem < Object class << self; attr_accessor :attributes; end @attributes = ['title', 'authors', 'location',] end class LibraryBook < LibraryItem @attributes.push('ISBN', 'pages') end
This does not work. I get the error
undefined method `push' for nil:NilClass
If it were to work, I would want something like this
puts LibraryItem.attributes puts LibraryBook.attributes
to output
['title', 'authors', 'location'] ['title', 'authors', 'location', 'ISBN', 'pages']
(Added 02-May-2010) One solution to this is to make
@attributes
a simple instance variable and then add the new attributes forLibraryBoot
in theinitialize
method (this was suggested by demas in one of the answers).While this would certainly work (and is, in fact, what I have been doing all along), I am not happy with this as it is sub-optimal: why should these unchanging arrays be constructed every time an object is created?
What I really want is to have class variables that can inherit from a parent class but when changed in the child class do not change in the the parent class.
解决方案Since you mention that the attributes are "fixed" and "unchanging", I am assuming that you mean that you will never change their value once the object is created. In that case, something like the following should work:
class Foo ATTRS = ['title', 'authors', 'location'] def attributes ATTRS end end class Bar < Foo ATTRS = ['ISBN', 'pages'] def attributes super + ATTRS end end
You are manually implementing a reader method (instead of letting
attr_accessor
create it for you) that disguises the internal name of the array. In your subclass, you simply call the ancestor class' reader function, tack on the additional fields associated with the child class, and return that to the caller. To the user, this appears like a read-only member variable namedattributes
that has additional values in the sub-class.这篇关于Ruby类的实例变量和继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!