从类外部访问实例变量

Posted

技术标签:

【中文标题】从类外部访问实例变量【英文标题】:Access instance variable from outside the class 【发布时间】:2012-08-20 19:19:21 【问题描述】:

如果一个实例变量属于一个类,我可以直接使用该类实例访问该实例变量(例如@hello)吗?

class Hello
  def method1
    @hello = "pavan"
  end
end

h = Hello.new
puts h.method1

【问题讨论】:

【参考方案1】:

是的,您可以像这样使用instance_variable_get

class Hello
  def method1
    @hello = "pavan"
  end
end

h = Hello.new
p h.instance_variable_get(:@hello) #nil
p h.method1                        #"pavan" - initialization of @hello
p h.instance_variable_get(:@hello) #"pavan"

如果变量未定义(在我的示例中第一次调用 instance_variable_get),您将得到 nil


正如安德鲁在他的评论中提到的:

您不应将此作为访问实例变量的默认方式,因为它违反了封装性。

更好的方法是定义访问器:

class Hello
  def method1
    @hello = "pavan"
  end
  attr_reader :hello  
end

h = Hello.new
p h.hello #nil
p h.method1                        #"pavan" - initialization of @hello
p h.hello #"pavan"

如果你想要另一个方法名,你可以别名访问器:alias :my_hello :hello

如果该类未在您的代码中定义,而是在 gem 中:您可以在代码中 modify classes 和 insert new functions to classes。

【讨论】:

您应该将此设置为访问实例变量的默认方式,因为它违反了封装性。 @knut 我们不能像h = Hello.newh.method1h.hello 那样做吗? @nlingutla 你可以用attr_reader :hello定义一个访问器 会不会是alias my_hello hello,而不是alias :my_hello :hello 对我来说,这非常适合规范,您不想公开某些内容。【参考方案2】:

您也可以通过调用attr_readerattr_accessor 来完成此操作,如下所示:

class Hello
  attr_reader :hello

  def initialize
    @hello = "pavan"
  end
end

class Hello
  attr_accessor :hello

  def initialize
    @hello = "pavan"
  end
end

调用attr_reader 将为给定变量创建getter

h = Hello.new
p h.hello        #"pavan"

调用attr_accessor 将为给定变量创建一个getter 和一个setter

h = Hello.new
p h.hello        #"pavan"
h.hello = "John"
p h.hello        #"John"

您可能会理解,请相应地使用attr_readerattr_accessor。仅在需要 gettersetter 时使用 attr_accessor,在仅需要 getter 时使用 attr_reader

【讨论】:

以上是关于从类外部访问实例变量的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中从类外部访问私有构造函数

Python,从类外部访问小部件项

内部类和外部类的实例变量可以共存

java内部类可以访问外部类的静态方法吗

如何从类内实例化的对象访问私有变量

python--定义实例方法