【问题标题】:Accessing subclass variables in a superclass in Ruby在 Ruby 中访问超类中的子类变量
【发布时间】:2022-01-05 16:11:44
【问题描述】:

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

In this lesson,在最后的练习中,我们被要求创建一个vehicle的超类并为其添加非特定行为,然后创建一个MyCar和一个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 方法,以便它返回一个字符串,该字符串将说明它是什么类型的车辆以及其他信息。现在,练习并没有要求我们这样做——事实上,他们为MyCarMyTruck 定义了一个to_s 方法,它以“我的车...”或“我的卡车...”开头,但是我觉得这违反了 DRY 原则。

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

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

请记住,我是新手!

提前致谢!

【问题讨论】:

    标签: ruby class oop


    【解决方案1】:

    没错。超类不能使用快捷方式VEHICLE_TYPE 来访问您定义的常量。

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

    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
    

    只要每个可实例化类都定义了该常量,这将起作用。

    【讨论】:

    • 它起作用了,但是限定名的概念对我来说仍然是陌生的。所以在Car::VEHICLE_TYPE 中,我们专门告诉ruby 检查Car 类中的VEHICLE_TYPE 常量?可以在程序的任何地方访问吗?
    • fully qualified name 是用于指定对象的明确名称。是的,常量是特殊的,可以在程序的任何地方使用。来自 O'Reilly 的 This description 很不错。
    猜你喜欢
    • 1970-01-01
    • 2017-08-22
    • 2012-04-09
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-07
    相关资源
    最近更新 更多