ruby - 类变量覆盖
问题描述
我在玩类变量,我知道我可以覆盖子类中的类变量,但我没有意识到我在哪里调用类方法很重要。例如;
class Vehicle
@@wheels = 4
def self.wheels
@@wheels
end
end
puts Vehicle.wheels #4
puts Vehicle.wheels #4
puts Vehicle.wheels #4
class Motorcycle < Vehicle
@@wheels = 2
end
该puts
语句输出 4,这对我来说都是有意义的,因为我认为在从类@@wheels
中实例化一个对象之前,您不会被覆盖。Motorcycle
所以我这样做了:
class Vehicle
@@wheels = 4
def self.wheels
@@wheels
end
end
class Motorcycle < Vehicle
@@wheels = 2
end
puts Vehicle.wheels #2
puts Vehicle.wheels #2
puts Vehicle.wheels #2
现在,一旦我将这三行移到类之后,Motorcycle
它们就会输出 2 ......即使一个Motorcycle
对象还没有被实例化。这让我很困惑。详细来说这里发生了什么?是因为当我们尝试访问它时加载了类变量吗?这怎么可能?
解决方案
首先,实例化与它无关;这是一个类变量,而不是实例变量。你的代码从不实例化任何东西;正如所写的那样,它也不需要。我们只是在谈论一些课程。但是类是 Ruby 中的一等对象,所以这很好。
其次,顺序很重要,因为在 Ruby 中所有语句都是可执行的。当你说
class Motorcycle < Vehicle
@@wheels = 2
end
...所有这些代码现在都在执行,就在你说它的那一刻——当 Ruby 遵从指令走下页面时遇到它的那一刻。该代码不仅仅是未来某个时间要遵守的模板;它说:“创建一个摩托车类并将其类变量设置wheels
为2
, now。”
第三,你没有“压倒”任何东西。在 Motorcycle类中,与您之前@@wheels
为@@wheels
Vehicle 定义的类变量完全相同。“覆盖”它的不是其他变量。这是一个单一的值,其工作方式类似于一种命名空间全局,可从类、任何子类及其任何实例访问。
有关更多信息,请参阅(例如):
如果你想要一些你可以覆盖的东西,你正在寻找的可能更像是类上下文中的一个实例变量,通常称为“类实例变量”——例如:
class Vehicle
@wheels = 4
class << self
attr_reader :wheels
end
end
class Motorcycle < Vehicle
@wheels = 2
end
puts Vehicle.wheels # 4
puts Motorcycle.wheels # 2
推荐阅读
- python - 我的自定义交叉熵损失函数有什么问题?
- jenkins - 在 slack 上显示测试报告
- java - 如何在 android 圆形手表上使用 recyclerview 制作圆形联系人列表?见附件
- email - 如何向订阅者发送完整的 html+images 邮件
- c# - 如何映射模型类以使集合之间存在关系?
- c# - 如何在 Xamarin 中的分组 ListItem 中创建动态列?
- react-native - Gradle Daemon 无法重用
- php - 动态多级菜单和子菜单 php mysql
- javascript - 从一种日期格式转换为另一种日期格式无效
- postgresql - 仅使用表空间文件恢复 PostgreSQL 数据库