18

有人可以解释一个类如何访问其超类的实例变量以及这不是继承吗?我说的是“Ruby 编程语言”和示例

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访问xy内部?to_s书上说:

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

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

4

4 回答 4

15

你是对的,这本书是错的,或者至少措辞不好


我会争辩说,这本书完全是错误的,或者充其量只是做出了一个相当混乱的解释。

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

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

这与所有其他 OO 系统相同。这本书关于运行哪个方法以及方法本身是如何真正继承的重要性的奇怪论点并没有增加清晰度。

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

于 2012-11-16T22:14:08.587 回答
7

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

于 2012-11-16T21:42:51.743 回答
1

它的措辞令人困惑。@x、@y 和 @z 都是该 Point3D 实例上的实例变量。如果该 super(x,y) 不存在,Point3D 实例将没有@x 或@y。

于 2012-11-16T21:43:31.703 回答
0

您可以比较这两个示例。

示例 1:似乎 B 继承@i自 A。

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并且@yinPoint3D实际上是由创建的Point#initialize(),而不是继承自Point

于 2018-09-19T03:21:36.887 回答