#ruby #subclass
#ruby #подкласс
Вопрос:
Допустим, у меня есть подкласс Sub класса Super и экземпляр Super с именем super . Как мне создать новый экземпляр Sub, который автоматически клонирует все свойства super (и включает дополнительные свойства Sub)? В качестве альтернативы, могу ли я создать новый экземпляр Super, а затем изменить его класс на Sub?
Подробнее:
Значение класса < Строка
attr_accessor ...fields...
def initialize(name, ...fields...)
...sets fields...
super(name)
end
def ...methods...
end
конец
class Extracted_Value
attr_accessor ...more fields...
def initialize(???)
???
end
конец
У меня есть куча разных экземпляров Value , и для каждого из них бывают случаи, когда я могу успешно выполнить извлечение из высказывания, что означает создание нового Extracted_Value, который содержит информацию о том, как произошло извлечение, но все из Value должно быть клонировано.
Мой другой вариант — попытаться создать какой-то класс-оболочку вместо подкласса?
Комментарии:
1. Вы пробовали что-нибудь до сих пор? Также: каков ваш реальный вариант использования для этого?
2. Есть способы сделать это, но очень сложно узнать правильный способ, не зная, как / почему вы хотите это сделать.
Ответ №1:
class A
attr_accessor :a1, :a2
def initialize param1, param2
@a1 = param1
@a2 = param2
end
end
class B < A
attr_accessor :b1
end
Когда вы создаете экземпляр класса B, вы можете вызывать как a1, так и a2 из (супер) класса, а также вызывать b1 . Вы можете объединить в методе инициализации подкласса параметры, которые вы хотите установить и т.д…
b = B.new "foo", 3
puts b.a1 # "foo"
puts b.a2 # 3
Надеюсь, это то, что вы хотели?
Комментарии:
1. Продолжая ваш пример: скажем, у нас уже есть a = A.новый «foo», 3 и мы вносим изменения в a с течением времени, например a.foo = «blah» Я хочу клонировать столько, сколько смогу, при создании b. Просто вызов инициализации A не сделает этого, он не будетне сохраняйте «бла»
Ответ №2:
Вы опасно приближаетесь к земле переменных класса, и все проблемы, с которыми вы сталкиваетесь, разделяют переменные между несколькими экземплярами объектов. Это почти всегда плохие новости.
Если у вас есть два объекта с одинаковыми свойствами, но разными значениями атрибутов, это должны быть два экземпляра одного и того же класса, который определяет свойства, а не два отдельных класса.
Вместо того, чтобы пытаться создать экземпляр другого класса, вы должны клонировать текущий экземпляр, чтобы получить новый экземпляр класса.
Поэтому ответ должен быть:
sub = Sub.new 'foo', 3
sub_two = sub.clone
puts sub_two.a1 # 'foo'
Ключевым моментом является то, что при использовании clone новый экземпляр просто копирует атрибуты в новый экземпляр, но не разделяет атрибуты между двумя объектами. Итак, вы можете сделать это:
sub.a1 = 'bar'
puts sub_two.a1 # 'foo'
puts sub.a1 # 'bar'
Комментарии:
1. Да, это отличное объяснение . Я думаю, что это вызывает параметры передачи по значению, не так ли?