MST
星途 面试题库

面试题:Ruby变量与常量作用域的复杂场景问题

假设有一个Ruby类继承体系,A类是父类,B类继承自A类。在A类中定义了一个类变量 @@class_var ,一个实例变量 @instance_var 和一个常量 CONST 。在B类中重新定义了一个同名常量 CONST 。请详细说明在B类的实例方法中访问这几个变量(包括重新定义的常量)时的解析过程和作用域情况,并编写代码验证你的结论。
33.8万 热度难度
编程语言Ruby

知识考点

AI 面试

面试题答案

一键面试
  1. 解析过程和作用域情况
    • 类变量 @@class_var
      • 在Ruby中,类变量是在整个继承体系中共享的。当在B类的实例方法中访问 @@class_var 时,它会从B类开始查找,由于B类没有重新定义该类变量,会沿着继承链向上查找,找到A类中定义的 @@class_var。它的作用域是整个继承体系,所有A类及其子类的实例都共享这个类变量。
    • 实例变量 @instance_var
      • 实例变量是属于每个实例对象的。在B类的实例方法中访问 @instance_var 时,会在当前实例对象的作用域内查找。如果B类的实例没有显式设置该实例变量,它不会从父类A中获取,而是为 nil(如果没有提前初始化)。它的作用域仅限于当前实例对象。
    • 常量 CONST
      • 在Ruby中,常量查找遵循就近原则。当在B类的实例方法中访问 CONST 时,会首先在B类中查找。由于B类重新定义了 CONST,所以会使用B类中定义的常量值。常量一旦定义,在同一个作用域内不能重新赋值(虽然Ruby不会严格报错,但会给出警告)。它的作用域是定义它的类及其子类(在子类没有重新定义的情况下,会使用父类的常量值)。
  2. 代码验证
class A
  @@class_var = "A's class variable"
  @instance_var = "A's instance variable"
  CONST = "A's constant"

  def print_vars
    puts "In A, @@class_var: #{@@class_var}"
    puts "In A, @instance_var: #{@instance_var}"
    puts "In A, CONST: #{CONST}"
  end
end

class B < A
  CONST = "B's constant"

  def print_vars
    puts "In B, @@class_var: #{@@class_var}"
    puts "In B, @instance_var: #{@instance_var}"
    puts "In B, CONST: #{CONST}"
  end
end

a = A.new
a.print_vars

b = B.new
b.print_vars

上述代码中,定义了A类和继承自A类的B类。在A类中定义了类变量、实例变量和常量,B类重新定义了常量。通过 a.print_varsb.print_vars 分别调用A类和B类的实例方法,可以验证变量和常量的解析过程和作用域情况。运行结果会显示:

  • A类实例中,类变量、实例变量和常量都是A类定义的值。
  • B类实例中,类变量是A类定义的值(因为共享),实例变量如果没有在B类实例中显式设置是 nil,常量是B类重新定义的值。