#r #oop #inheritance #r6
#r #ооп #наследование #r6
Вопрос:
У меня есть простой генератор объектов R6:
thing <- R6Class("youngThing",
private = list(
..age = 0),
active = list(
age = function(){
private$..age <- private$..age 1
private$..age
}
)
)
Это дает мне простой объект R6, который ..age
увеличивается на 1 при каждом вызове активного age
поля:
a_thing <- thing$new()
a_thing$age
# [1] 1
Я хочу, чтобы класс объекта a_thing изменялся с учетом порогового значения частного поля ..age
, например:
class(a_thing)
# [1] "youngThing" "R6"
for(timestep in 1:10){
if(a_thing$age >5 amp; ! inherits(a_thing, "olderThing")){
class(a_thing) <- c("olderThing", class(a_thing))
}
}
class(a_thing)
# [1] "olderThing" "youngThing" "R6"
Однако я хочу, чтобы это происходило внутри объекта. Есть ли способ включить это в качестве активной привязки в генератор объектов, чтобы любой созданный из него объект имел встроенную эту функциональность?
ПРИМЕЧАНИЕ. Предпочтительно, чтобы пороговый класс добавлялся к объекту; что он не заменяет существующие классы.
Комментарии:
1. Изменение класса кажется немного странным выбором дизайна. Почему бы просто не иметь общедоступный
is_old
логический флаг, который можно запрашивать по мере необходимости?2. Я ожидаю, что будут некоторые ответы, которые сделают это возможным технически, но дважды подумайте о том, что это значит с точки зрения дизайна. Что, если вы присвоите объект переменной, затем вызовете метод, чтобы класс изменился, а затем вызовите функцию, которая ожидает старый класс с объектом. Это нарушает некоторые предположения, обычно сделанные относительно (неизменяемого) класса объекта, и может привести к проблемам позже.
3. @AllanCameron Привет, спасибо за комментарий. В ситуации, когда один объект является одним человеком, я могу использовать универсальный метод S3 для реализации другого метода в зависимости от класса (возраста) объекта (человека).
4. @jayb или у вас может быть один метод, который проверяет поле age и ведет себя соответствующим образом?
Ответ №1:
Вы можете изменить класс self
.
library(R6)
thing <- R6Class(
"youngThing",
private = list(..age = 0),
active = list(
age = function() {
private$..age <- private$..age 1
if(private$..age > 5 amp;amp; !inherits(self, "olderThing")){
class(self) <- c("olderThing", class(self))
}
private$..age
}
)
)
a_thing
пока имеет исходный класс age <= 5
.
a_thing <- thing$new()
a_thing$age; a_thing$age; a_thing$age; a_thing$age; a_thing$age
#> [1] 2
#> [1] 3
#> [1] 4
#> [1] 5
class(a_thing)
#> [1] "youngThing" "R6"
Затем он обновляется после завершения 5
.
a_thing$age
#> [1] 6
class(a_thing)
#> [1] "olderThing" "youngThing" "R6"