访问父类实例变量

时间:2010-05-20 14:19:21

标签: ruby instance-variables

这怎么办?

class A
  attr_accessor :name

  def initialize params
    @name = params[:name]
    @collection << B.new 
  end
end

class B < A
  def initialize
    @my_name = lookup_something(<parent.name>)
  end
end

基本上,我需要来自父类的值来在子类的查找中使用,但是如果有更好的方法,我不想明确地传递它。父类的实例var是否在子类中完全无法访问?或者这只是糟糕的层次结构设计?

3 个答案:

答案 0 :(得分:8)

我真的不知道你在这里要做什么 - 你发布的所有代码都适用于实例变量。实例变量是每个对象,而不是每个类,所以当你说“我需要来自父类的值”时,我不知道你的意思。

我在您的代码中注意到以下几点:

  • 基类应该从不了解子类。因此,在B中创建A#initialize对象并不是一件好事,因为基类使用子类。
  • 您正在使用与B#initialize完全不同的行为覆盖班级A#initialize您甚至可以更改参数列表。也不是一件好事。子类的对象应该与其超类的对象的行为方式相同。
  • 当您致电B.new('myname')时,永远不会分配变量@name,因为永远不会调用A#initialize方法。您必须致电super(:name => name)(以运行超类initialize),或者您必须直接在@name
  • 中分配给B#initialize
  • 定义@name后,所有实例方法都可以使用其值。包括在父/超类中定义的那些。

让我说我不太清楚为什么你在这里使用继承,我觉得它不是你想要的。如果您有两个不同事物的类,则应该从不继承。如果要重用代码,可以查看Ruby的mixin功能,或者编写具有您想要重用的行为的几个“较小”对象的复杂对象。

答案 1 :(得分:3)

John Nunemaker在这个主题上有一个很好的article

答案 2 :(得分:2)

您希望BA继承的原因是什么?除非你有其他原因,设计这个的正确方法是简单地将名称作为B的构造函数的参数并放弃继承。

class A
  attr_accessor :name

  def initialize params
    @name = params[:name]
    @collection << B.new(@name)
  end
end

class B
  def initialize name
    @my_name = lookup_something(@name)
  end
end