Слоты класса против инициализации несовпадения сигнатур
Рассмотрим следующий класс S4:
setClass('Foo', representation(model='data.frame'))
setMethod('initialize', 'Foo',
function(.Object, a, b) {
.Object@model <- data.frame(a, b)
.Object
})
Это может быть реализовано с помощью:
new('Foo', a=1:4, b=4:7)
Все идет нормально. Однако, когда я пытаюсь создать подкласс Foo, я получаю сообщение об ошибке.
setClass('Bar', contains='Foo')
>>> Error in data.frame(a, b) : argument "a" is missing, with no default
Лично я предпочел бы создать экземпляр класса Foo с явными аргументами, потому что код более... хорошо, явный. Однако это не представляется возможным, не так ли? Похоже, подпись initialize
должен совпадать со слотами, которые есть у класса, иначе это проблема, ожидающая своего появления. Я ошибся?
1 ответ
Требование заключается в том, что new
звонил без аргументов, new("Foo")
, должно работать. Кроме того, вероятно, лучше использовать метод инициализации ...
, чтобы callNextMethod
и иметь аргументы после ...
(так как initialize
задокументировано использование безымянных аргументов для инициализации содержащихся классов). Так
setMethod(initialize, "Foo", function(.Object, ..., a=integer(), b=integer()) {
callNextMethod(.Object, ..., model=data.frame(a, b))
})
Обычно каждый хочет изолировать пользователя от вызова нового, и вместо этого будет использовать конструктор Foo
, Обычно конструктор делает все возможное принуждение вместо того, чтобы поместить его в метод инициализации, поэтому метод инициализации просто не указан.
Foo <- function(a=integer(), b=integer(), ...) {
model <- data.frame(a, b)
new("Foo", model=model, ...)
}