【问题标题】:How to access child's instance variable in super / parent class如何在超级/父类中访问孩子的实例变量
【发布时间】:2019-03-17 14:02:06
【问题描述】:

我有以下例子:

class A
   @Values = {}

   def initialize()
     @Values.each{ |_key, _val|
        puts("Key: #{_key}, Val: #{_val}")
     }
   end
end

class B < A
  @Values = { "Test1": "1", "Test2": "2"}

  def initialize()
    super()
  end
end

我的问题:

B.new()

不创建输出 - 所以来自 B 类的 @Values 在 A 类中不可用。为什么?如何访问它们?

========= 更新========= 谢谢您的回答!

@Mosab Muhammad:是的 - 我真的不确定何时使用 {} 以及何时使用 do end ...我会看看两者何时使用。

{}(通常用于单行块)或 do..end(用于 多行块)。

没错 - 我读到这样做是一种铁路惯例,但还有更多 - {} 并且确实表现不同。

@@ 是一个选项,但我认为编辑类变量不是一个好主意 - 正如您所提到的,它可能会产生非常讨厌的副作用。

@Aleksei Matiushkin - 谢谢!我将查看 self.class.instance_variable_get 并查看它的行为方式以及它是否能解决我的问题!

非常感谢!

【问题讨论】:

  • 嗨。如果一些答案有帮助,张贴者将不胜感激。接受最佳答案将不胜感激。

标签: ruby class inheritance instance-variables


【解决方案1】:

您的问题@Values from class B are not available in class A. Why?的答案是: 在类级别声明的实例变量不能在对象级别访问。

您的问题How can i access them? 的答案是:您可以在initialize 方法中声明一个类变量@@values 而不是实例变量@values

您的示例将更改为:

class A
  @@values = {}

  def initialize()
    @@values.each{ |_key, _val|
      puts("Key: #{_key}, Val: #{_val}")
    }
  end
end

class B < A
  @@values = { "Test1": "1", "Test2": "2"}
end

现在B.new会输出

Key: Test1, Val: 1
Key: Test2, Val: 2

另一个答案:

class A

   def initialize()
     @values ||= {}
     @values.each{ |_key, _val|
        puts("Key: #{_key}, Val: #{_val}")
     }
   end
end

class B < A

  def initialize()
    @values = { "Test1": "1", "Test2": "2"}
    super()
  end
end

注意:类变量在相关类之间共享,并且可以从子类中覆盖。这意味着如果您覆盖 B 类中的类变量 @@values,则 A 类中的 @@values 将被覆盖。

另一个注意事项:{}(通常用于单行块)或 do..end(用于多行块)。

例如: 使用

def initialize()
  @Values.each{ |_key, _val| puts("Key: #{_key}, Val: #{_val}") }
end

代替:

def initialize()
  @Values.each{ |_key, _val|
    puts("Key: #{_key}, Val: #{_val}")
  }
end

使用

def initialize()
  @Values.each do |_key, _val|
    puts("Key: #{_key}, Val: #{_val}")
  end
end

代替:

def initialize()
  @Values.each{ |_key, _val|
    puts("Key: #{_key}, Val: #{_val}")
  }
end

【讨论】:

  • 这不是问题所在。它是关于实例变量,而不是类变量。
  • 我告诉过你,在类级别声明的实例变量(在你的情况下为@values)不能在对象级别访问(即:在初始化方法中)
  • 好吧,不过还是没有回答这个问题。
  • 知道了,我更新了我的答案以包含您想要的答案。请注意,实例变量应在不在类范围内的方法内声明。
【解决方案2】:

嗯,这段代码有很多问题,所以我会回答所说的确切问题。如果您希望变量可以从类和即时上下文中访问,请改用 类变量

class A
  @@values = {}
  def initialize
    @@values.each{ |key, val|
      puts("Key: #{key}, Val: #{val}")
    }
  end
end

class B < A
  @@values = { "Test1" => "1", "Test2" => "2"}
  def initialize
    super
  end
end

B.new
#⇒ Key: Test1, Val: 1
#  Key: Test2, Val: 2

【讨论】:

  • 这不是问题所在。它是关于实例变量,而不是类变量。
  • @mbuechmann 让我自己决定如何以及如何回答。顺便说一句,您的回答违反了 SRP(您的父类实现取决于子,这很愚蠢。)
  • 当然欢迎大家随意回答。我的评论仍然有效,应该允许我指出一些事情。
猜你喜欢
  • 1970-01-01
  • 2019-04-10
  • 2011-02-21
  • 2010-10-23
  • 1970-01-01
  • 1970-01-01
  • 2018-08-15
  • 2011-10-07
相关资源
最近更新 更多