Наследование переменных экземпляра
Может кто-нибудь объяснить, как класс может получить доступ к переменным экземпляра своего суперкласса и как это не наследование? Я говорю о "языке программирования 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
если они не унаследованы? Книга говорит:
"Причина, по которой они иногда кажутся наследуемыми, заключается в том, что переменные экземпляра создаются методами, которые сначала присваивают им значения, и эти методы часто наследуются или связываются".
но я не могу понять, что это на самом деле означает.
4 ответа
Вы правы, книга не права или, по крайней мере, плохо сформулирована
Я бы сказал, что книга просто неверна, или, в лучшем случае, дает довольно грязное объяснение.
Во всех ОО-языках суперкласс и производный класс не имеют отдельных объектов. Когда вы создаете экземпляр производного класса, он также является экземпляром суперкласса. Есть один объект, и это оба класса одновременно.
Поскольку существует только один объект, существует только один набор переменных экземпляра.
Это так же, как и все другие системы OO. Странный аргумент, который приводит эта книга о том, как важно то, какой метод запускается и как сами методы являются тем, что на самом деле наследуется, не добавляет много ясности.
Проблема с терминологией заключается в том, что, конечно же, в динамически типизированной системе вообще нет декларации, и поэтому, безусловно, определение подкласса не наследует никаких деклараций полей... потому что, конечно, их нет., Но то, что нет наследуемых типов, не делает противоположное утверждение ("переменные экземпляра не наследуются") более верным, и это добавляет немало путаницы, поскольку подразумевает, что каким-то образом родитель будет иметь разные переменные экземпляра, что является бессмысленным результатом попытки говорить об объектах так, как они это делают.
super(x,y)
вызывает конструктор базового класса, который является методом инициализации. Если вы берете super(x,y)
затем переменные @x
а также @y
не появится в производном классе.
Это смутно сформулировано. @x, @y и @z - все переменные экземпляра в этом экземпляре Point3D. Если бы этого супер (x,y) не было, экземпляр Point3D не имел бы @x или @y.
Вы можете сравнить эти два примера.
Пример 1: кажется, B наследуют @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
"s @i
в примере 1 фактически создается неявно A#initialize()
когда вы вызываете B.new()
,
В твоем случае, @x
а также @y
в Point3D
на самом деле создан Point#initialize()
не наследуется от Point