有人可以解释一个类如何访问其超类的实例变量以及它不是如何继承?我在谈论'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
类未被继承,x
如何访问y
和to_s
?这本书说:
“它们有时似乎是继承的原因是实例变量是由首先为它们赋值的方法创建的,而这些方法通常是继承或链接的。”
但我无法弄清楚它的真正含义。
答案 0 :(得分:12)
我认为这本书是完全错误的,或者充其量,这是一个非常混乱的解释。
在所有OO语言中,超类和派生类没有单独的对象。当您创建派生类的实例时,也是超类的实例。有一个对象,它同时是两个类。
由于只有一个对象,因此只有一组实例变量。
这与所有其他OO系统相同。书中关于如何运行哪个方法以及方法本身如何实际继承的奇怪论证并没有增加太多的清晰度。
术语的问题是,当然,在动态类型系统中,首先没有声明,因此子类的定义肯定不会继承任何字段声明......因为当然没有不管怎样。但仅仅因为没有类型可以继承不会使相反的语句(“实例变量不被继承”)更加真实,并且它会增加相当多的混淆,因为它暗示父母会以某种方式使不同实例变量,这是尝试以他们的方式谈论对象的荒谬结果。
答案 1 :(得分:7)
super(x,y)
调用基类的构造函数,这是initialize方法。
如果您取消super(x,y)
,则变量@x
和@y
不会出现在派生类中。
答案 2 :(得分:1)
措辞令人困惑。 @x,@ y和@z是该Point3D实例上的所有实例变量。如果那个超级(x,y)不存在,那么Point3D实例将没有@x或@y。
答案 3 :(得分: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
中的@y
和Point3D
实际上是由Point#initialize()
创建的,而不是从Point
继承的