在 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 都定义了该常量,这就可以工作。
所以,我已经学习 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 都定义了该常量,这就可以工作。