Ruby可以子类化实例变量_overwrite_超类(同名)吗?
在“
ruby编程语言”一书的第7.3.5节“继承和实例变量”中说:
我做了自己的测试,但似乎来自子类的实例变量不会影响超类 我的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> 解决方法
这本书(重点和补充我的):
我知道你没有同一个班级的两个实例;我们专门讨论继承问题. 当子类使用与超类使用的实例变量同名的实例变量时,就会有一个实例变量.如果子类更改了该实例变量的值,并且超类访问它,则它将获取子类设置的值. 当子类被实例化时,它“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引入了一个错误,因为它无意中使用了与用于保存堆栈内容的超类数组相同的名称.如果您不熟悉超类的实现,这将导致混乱和错误,直到您深入挖掘以了解意外行为的来源. 超类的一个实例就是:超类的一个实例,谈论子类的实例将如何影响它是没有意义的,因为它们完全不相关. 这是一个改写:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |