在 Ruby 中访问超类中的子类变量

Accessing subclass variables in a superclass in Ruby

所以,我已经学习 Ruby 两个多星期了,但我在理解整个 OOP 方面遇到了一些问题。

In this lesson,在最后的练习中,我们被要求创建一个vehicle的超类并为其添加非特定行为,然后创建一个MyCar和a MyTruck 个从它继承的子类,也有一个常量将它们分开。所以我就这样做了:

class Vehicle

  attr_accessor :color, :curr_speed
  attr_reader :year, :model

  def initialize(y, c, m)
    @year = y
    @color = c
    @model = m
  end

  #SOME OTHER METHODS

  def to_s
    "My #{VEHICLE_TYPE} is a #{self.model} #{self.year} of color #{self.color}."
  end      
end

class MyCar < Vehicle
  VEHICLE_TYPE = 'car'
end

class MyTruck < Vehicle
  VEHICLE_TYPE = 'truck'
end

我还重新定义了 to_s 方法,这样它会 return 一个字符串,说明它是什么类型的车辆以及其他信息。现在,练习并没有要求我们这样做——事实上,他们为 MyCar 定义了一个 to_s 方法,为 MyTruck 定义了另一个以“My car...”开头的方法,或者“我的卡车……”但我觉得这违背了DRY原则。

事实是,Ruby 似乎不接受在超类方法中传递的子类变量。如果我使用 #{VEHICLE_TYPE} 它会抛出一个 uninitialized constant Vehicle::VEHICLE_TYPE (NameError),如果我使用 #{self.VEHICLE_TYPE} 它会抛出一个 undefined method 'VEHICLE_TYPE' for Vehicle:Class (NoMethodError).

我的假设是否正确 Ruby 不接受超类中的子类变量?我怎样才能以类似的方式解决这个问题呢?因为我考虑简单地向 initizalize 添加另一个参数作为类型,存储在超类实例变量中并完成它,但我认为它不会达到练习的目的。

请记住,我是新手!

提前致谢!

没错。 superclass 不能使用 VEHICLE_TYPE 的快捷符号来访问您定义的常量。

当你想访问它定义的 class 之外的常量时,你可以使用限定名称访问它,例如:

Car::VEHICLE_TYPE

您的 self.VEHICLE_TYPE 尝试已经非常接近了。但是要为 Car:: 之类的内容提供通用替换,您需要使用 self.class::.

所以你的 to_s 方法看起来像:

def to_s
  "My #{self.class::VEHICLE_TYPE} is a #{self.model} #{self.year} of color #{self.color}."
end

只要每个实例化 class 都定义了该常量,这就可以工作。