Ruby类的实例变量和继承 [英] Ruby class instance variables and inheritance

查看:112
本文介绍了Ruby类的实例变量和继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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 called LibraryBook that has an array of attributes that includes all the attributes of LibraryItem 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 to LibraryItem'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 for LibraryBoot in the initialize 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 named attributes that has additional values in the sub-class.

这篇关于Ruby类的实例变量和继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆