S4 помогает нам раскрашивать линии. Таким образом, ваш класс fb
должен быть виртуальным, а метод initialize
не должен изменять класс .Object
. Вы могли бы написать функцию fb
, которая выполняет ваше условное создание.
setClass("fb", representation( x = "numeric", "VIRTUAL"))
setClass("foo", contains = "fb")
setClass("bar", contains = "fb")
fb <-
function(x)
{
if (x < 5) new("foo", x=x)
else new("bar", x=x)
}
fb
- это более удобный для пользователя конструктор, который отделяет интерфейс к вашей иерархии классов от его реализации, которая обычно считается хорошей.
И для чего стоит неявное ограничение на методы S4 initialize
, так это то, что new("foo")
(вызывая new
с именем класса, но без дополнительных аргументов) должен работать (в противном случае возникают ошибки при попытке расширить foo) , Таким образом, парадигма для метода инициализации в соответствии с
setMethod(initialize, "foo", function(.Object, ..., x=1) {
.Object <- callNextMethod(.Object, ...)
.Object@x <- x
.Object
})
хотя часто (как в этом случае, когда initialize
просто выполняет назначение слотов), метод инициализации вообще не нужен. Обратите внимание на использование ...
, позиционирование x
(требующее, чтобы аргумент был назван в соответствующем вызове new
) и использование значения по умолчанию.