Ruby 子类实例变量可以覆盖超类(同名)的实例变量吗?

2024-01-24

在《Ruby编程语言》一书中的第7.3.5章“继承和实例变量”中说:

因为实例变量与 继承,因此子类使用的实例变量不能“隐藏” 超类中的实例变量。如果子类使用相同的实例变量 name 作为其祖先之一使用的变量,它将覆盖其>祖先的价值 多变的。这可以是有意为之,以改变祖先的行为,也可以 不经意间就完成了。在后一种情况下,几乎肯定会导致错误。与 前面描述的私有方法的继承,这是它唯一的另一个原因 当您熟悉(并控制)时,可以安全地扩展 Ruby 类 超类的实现。

我做了自己的测试,但似乎子类的实例变量不会影响超类

我的红宝石版本

bob@bob-ruby:~$ ruby --version
ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux]
bob@bob-ruby:~$ 

下面是代码

class Point
   attr_accessor :x,:y
   def initialize(x,y)
     @x,@y=x,y
   end
end

class Point3D < Point
   attr_accessor :x,:y,:z
   def initialize(x,y,z)
     @x=x
     @y=y
     @z=z
   end
end

irb(main):052:0> p=Point.new(1,2)
=> #<Point:0x87e8968 @x=1, @y=2>
irb(main):053:0> q=Point3D.new(4,5,6)
=> #<Point3D:0x87e423c @x=4, @y=5, @z=6>
irb(main):054:0> q.x
=> 4
irb(main):055:0> p.x
=> 1
irb(main):056:0> 

这本书(重点和补充是我的):

If a subclass使用一个instance如果变量与其祖先之一使用的[n实例]变量同名,它将覆盖其祖先变量的值。

我知道你没有同一类的两个实例;我们正在专门讨论继承。

当子类使用与超类使用的实例变量同名的实例变量时,就有一个实例变量。如果子类更改该实例变量的值,并且超类访问它,它将获取子类设置的值。

当子类被实例化时,它的行为“就好像”它是also超类的一个实例。 Ruby 的实现方式意味着如果超类有一个实例变量@foo,子类可以访问它。这使得子类之间有所区别@foo和超类的@foo无意义的。

这就是子类改变超类行为的方式:通过设置超类可能使用的值。如果子类设置@foo = 42,并且超类方法访问@foo,它看到42。这可能是有意的,也可能不是有意的,因此发出警告。它可能会导致极其令人沮丧的调试会话。

class MyStack
  def initialize
    @my_array = []
  end

  def push(item)
    @my_array << item
  end
end

# Stack class that keeps a list 
# of every item ever pushed.
class TrackingStack < MyStack
  def initialize
    super
    @my_array = []
  end

  def push(item)
    super
    @my_array << item
  end

  def all_items_ever_pushed
    @my_array
  end
end

TrackingStack引入了一个错误,因为它无意中使用了与用于保存堆栈内容的超类数组相同的名称。如果您不熟悉超类的实现,这会导致混乱和错误,直到您深入挖掘以了解意外行为的来源。

超类的一个实例就是:instance超类的,谈论如何instance of the subclass会影响它,因为它们完全无关。

这是一个改写:

当您无法控制或不熟悉超类实现时,子类化可能会存在风险。原因之一是在子类中引入实例变量可能会覆盖超类实例变量的值,从而导致意外行为。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ruby 子类实例变量可以覆盖超类(同名)的实例变量吗? 的相关文章

随机推荐

  • 在 Windows Phone 上实现可滚动表格

    我需要创建一个电视指南应用程序 要求是 UI 必须是您可以在此处看到的 UI 的副本 raspored bnet hr http raspored bnet hr 正如您所看到的 有很多数据 所以 基本上它是一个大的可滚动表格 由于 Win
  • 将 C++ 模板参数限制为子类

    如何强制模板参数T成为特定类的子类Baseclass 像这样的东西 template
  • Django Ckeditor 图像浏览器找不到图像

    所以我正在建立一个简单的博客来跟踪我的项目 我决定使用 CKeditor 作为所见即所得编辑器 除了图像部分之外 我能够使其所有内容正常工作 当我点击 图像浏览 时 我无法查看服务器中的图像 并且每当我上传图像时 它都会上传 但我无法查看它
  • 颠覆外部是一种反模式吗?

    Subversion 允许您使用以下方式嵌入其他存储库的工作副本外部因素 http svnbook red bean com en 1 1 ch07s04 html 可以轻松地对项目中的第三方库软件进行版本控制 虽然这些对于库的重用和版本控
  • 使用发送事件通过编程创建的 Dropzone 发送附加数据

    我有以下 例如简化的 角度指令 它创建一个放置区 directives directive dropzone dropZoneFactory function dropZoneFactory use strict return restri
  • MySQL排序后如何选择更多行?

    我有一个表 其中有 10 个结果 我们来说说以下几点 id user number 1 user1 10 2 user2 5 3 user3 30 4 user4 45 5 user5 5 6 user6 22 7 user7 10 8 u
  • UICollectionView 不在 UITableViewCell 内滚动

    我在 UITableViewCell 内滚动 UICollectionView 时遇到问题 不幸的是 CollectionView 根本不滚动 当我尝试禁用其他 UITableViewCells 时 它可以正常工作 反之亦然 集合视图单元格
  • 将 Android 矢量绘图转换为启动器图标 PNG

    我已经将 Android 启动器图标制作为矢量 但我发现我应该使用 PNG 而不是矢量 XML 如何将我的矢量图像转换为 PNG 作为启动器图标 如果有帮助的话 这是矢量
  • 对于大列表,我可以使用嵌套线性布局而不是列表视图吗?

    我正在下载大量图像和文字 就像 Facebook 帖子一样 来自服务器 因此 当列表视图滚动时 它会在创建回收视图时闪烁 所以我想对我的主线性布局中的每个帖子使用多个线性布局 这样的话 会不会有滚动性能或者内存消耗的问题呢 请帮忙 肯定会存
  • Redis 存储没有值的键

    使用Redis时expire命令如SETEX https redis io commands setex and TTL https redis io commands ttl 在某些情况下 密钥根本不需要保存值 因为生存时间就这样行事 然
  • 应用程序加载器无法选择我的 Mac 应用程序的 zip 文件

    我的 Mac 应用程序的状态是 等待上传 当我启动应用程序加载器时 我可以从列表中选择它 但是 当我单击 选择 时 我无法选择应用程序的 zip 文件 或任何其他任何类型的文件 我尝试上传一个 iPhone 应用程序 看看应用程序加载器是否
  • 如何通过 VS Code Azure 帐户扩展切换帐户

    我已通过 VS Code 使用 Azure 帐户扩展登录我的 Azure 帐户之一 我没有找到任何退出或切换帐户的按钮 如何退出或切换帐户 您找不到使用 Azure 帐户扩展在 VS Code 中登录或注销的按钮 该扩展适用于命令面板中的命
  • 使用 JasperPrintManager.printReport(print, true) 打印 jasper 报告时出错;

    下面是我的代码 Map parameters new HashMap parameters put printer 1010111 FileInputStream file new FileInputStream new File getS
  • 如何为许多子图制作一个图例?

    我正在绘制相同类型的信息 但针对不同的国家 地区 并使用 Matplotlib 绘制多个子图 也就是说 我在 3x3 网格上有九个图 所有图都具有相同的行 当然 每行的值不同 但是 我还没有弄清楚如何在图形上放置一次图例 因为所有九个子图都
  • Azure Active Directory、应用程序注册、带哈希的回复 URL

    我希望在通过 Azure AD 登录后导航回 Angular 应用程序 我想要的回复网址是 http localhost 4200 authcallback http localhost 4200 authcallback 我尝试转义 ht
  • 如何在不继承句柄的情况下分叉进程?

    在我在 Mac 达尔文内核版本 10 4 0 上运行的 C C 服务器应用程序中 我正在分叉子进程 并希望这些子进程不继承服务器的文件句柄 文件 套接字 管道等 似乎默认情况下所有句柄都被继承 甚至netstat显示子进程正在监听服务器的端
  • 创建4.0蓝牙传输的socket

    我正在开发一个 Android 应用程序 可以将数据传输到 4 0 蓝牙串行设备 我正在指导 LeGatt android 示例项目 http developer android com samples BluetoothLeGatt in
  • Python:Collections.Counter 与 defaultdict(int)

    假设我有一些如下所示的数据 Lucy 1 Bob 5 Jim 40 Susan 6 Lucy 2 Bob 30 Harold 6 我想结合 删除重复的键 并且 添加这些重复键的值 这意味着我会得到键 值 Lucy 3 Bob 35 Jim
  • C# 中的枚举和组合框

    我目前正在开发一个 C 应用程序 我需要使用带有组合框的枚举来获取选定的月份 我有以下内容来创建枚举 enum Months January 1 February March April May June July August Septe
  • Ruby 子类实例变量可以覆盖超类(同名)的实例变量吗?

    在 Ruby编程语言 一书中的第7 3 5章 继承和实例变量 中说 因为实例变量与 继承 因此子类使用的实例变量不能 隐藏 超类中的实例变量 如果子类使用相同的实例变量 name 作为其祖先之一使用的变量 它将覆盖其 gt 祖先的价值 多变