实例变量继承

问题描述 投票:14回答:4

有人可以解释一个类如何访问其超类的实例变量以及它不是如何继承?我在谈论'Ruby Programming Language'和示例

class Point
  def initialize(x,y) # Initialize method 
     @x,@y = x, y      # Sets initial values for instance variables
  end

end

class Point3D < Point
 def initialize(x,y,z)
   super(x,y)
   @z = z
 end
 def to_s
   "(#@x, #@y, #@z)"  # Variables @x and @y inherited?
 end
end

Point3D.new(1,2,3).to_s => "(1, 2, 3)"

如果Point3D不是继承的话,怎么能在x中访问yto_s?这本书说:

“它们有时似乎是继承的原因是实例变量是由首先为它们赋值的方法创建的,而这些方法通常是继承或链接的。”

但我无法弄清楚它的真正含义。

ruby inheritance instance-variables
4个回答
12
投票

You are right, the book is wrong, or at least poorly worded


我认为这本书是完全错误的,或者充其量,这是一个非常混乱的解释。

在所有OO语言中,超类和派生类没有单独的对象。创建派生类的实例时,它也是超类的实例。有一个对象,它同时是两个类。

由于只有一个对象,因此只有一组实例变量。

这与所有其他OO系统相同。本书关于如何运行哪个方法以及方法本身如何实际继承的奇怪论证并没有增加太多的清晰度。

术语的问题是,当然,在动态类型系统中,首先没有声明,因此子类的定义肯定不会继承任何字段声明......因为当然没有任何声明。但是因为没有类型可以继承不会使相反的语句(“实例变量不被继承”)更加真实,并且它会增加相当多的混淆,因为它暗示父母会以某种方式拥有不同的实例变量,这是试图以他们的方式谈论对象的荒谬结果。


7
投票

super(x,y)调用基类的构造函数,这是initialize方法。如果你取super(x,y),那么变量@x@y将不会出现在派生类中。


1
投票

措辞令人困惑。 @x,@ y和@z是该Point3D实例上的所有实例变量。如果不存在超级(x,y),则Point3D实例将不具有@x或@y。


0
投票

您可以比较这两个示例。

例1:似乎B从A继承了@i

class A
  def initialize()
    @i = "ok"
  end
end

class B < A
  def print_i()
    p(@i)
  end
end

B.new().print_i()   # Shows "ok"

例2:如果B有自己的initialize(),则找不到@i

class A
  def initialize()
    @i = "ok"
  end
end

class B < A
  def initialize()
  end

  def print_i()
    p(@i)
  end
end

B.new().print_i()   # nil, print nothing

class B在示例1中的@i实际上是在你调用A#initialize()时由B.new()隐式创建的。

在你的情况下,@x中的@yPoint3D实际上是由Point#initialize()创建的,不是继承自Point

© www.soinside.com 2019 - 2024. All rights reserved.