Because instance variables have nothing to do with
inheritance,it follows that an instance variable used by a subclass cannot “shadow” an
instance variable in the superclass. If a subclass uses an instance variable with the same
name as a variable used by one of its ancestors,it will overwrite the value of its >ancestor’s
variable. This can be done intentionally,to alter the behavior of the ancestor,or it can
be done inadvertently. In the latter case,it is almost certain to cause bugs. As with the
inheritance of private methods described earlier,this is another reason why it is only
safe to extend Ruby classes when you are familiar with (and in control of) the
implementation of the superclass.
我做了自己的测试,但似乎来自子类的实例变量不会影响超类
我的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 uses an instance variable with the same name as a[n instance] variable used by one of its ancestors,it will overwrite the value of its ancestor’s variable.
我知道你没有同一个班级的两个实例;我们专门讨论继承问题.
当子类使用与超类使用的实例变量同名的实例变量时,就会有一个实例变量.如果子类更改了该实例变量的值,并且超类访问它,则它将获取子类设置的值.
当子类被实例化时,它“as-if”它也是超类的一个实例.实现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引入了一个错误,因为它无意中使用了与用于保存堆栈内容的超类数组相同的名称.如果您不熟悉超类的实现,这将导致混乱和错误,直到您深入挖掘以了解意外行为的来源.
超类的一个实例就是:超类的一个实例,谈论子类的实例将如何影响它是没有意义的,因为它们完全不相关.
这是一个改写:
Subclassing can be risky when you don’t control,or are unfamiliar with,the superclass implementation. One reason is because the introduction of an instance variable in the subclass may overwrite the value of a superclass instance variable,leading to unintended behavior.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。