new {methods} | R Documentation |
Given the name or the definition of a class, plus optionally data
to be included in the object, new
returns an object from that
class.
new(Class, ...)
initialize(.Object, ...)
Class |
Either the name of a class (the usual case) or the
object describing the class (e.g., the value returned by
|
... |
Data to include in the new object. Named arguments correspond to slots in the class definition. Unnamed arguments must be objects from classes that this class extends. |
.Object |
An object: see the Details section. |
The function new
begins by copying the prototype object from
the class definition. Then information is inserted according to the
...
arguments, if any. As of version 2.4 of R, the type of
the prototype object, and therefore of all objects returned by
new()
, is "S4"
except for classes that extend
one of the basic types, where the prototype has that basic type. User
functions that depend on typeof(object)
should be
careful to handle "S4"
as a possible type.
The interpretation of the ...
arguments can be specialized to
particular classes, if an appropriate method has been defined for the
generic function "initialize"
. The new
function calls
initialize
with the object generated from the prototype as the
.Object
argument to initialize
.
By default, unnamed arguments in the ...
are interpreted as
objects from a superclass, and named arguments are interpreted as
objects to be assigned into the correspondingly named slots. Thus,
explicit slots override inherited information for the same slot,
regardless of the order in which the arguments appear.
The initialize
methods do not have to have ...
as
their second argument (see the examples). Initialize methods are
often written when the natural parameters describing the new object
are not the names of the slots. If you do define such a method,
note the implications for future subclasses of your class. If these
have additional slots, and your initialize
method has
...
as a formal argument, then your method should pass such
arguments along via callNextMethod
. If your method
does not have this argument, then either a subclass must have its
own method or else the added slots must be specified by users in
some way other than as arguments to new
.
For examples of initialize
methods, see
initialize-methods
for existing methods for
classes "traceable"
and "environment"
, among others.
Methods for initialize
can be inherited only by simple
inheritance, since it is a requirement that the method return an
object from the target class. See the
simpleInheritanceOnly
argument to setGeneric
and
the discussion in setIs
for the general concept.
Note that the basic vector classes, "numeric"
, etc. are
implicitly defined, so one can use new
for these classes.
Chambers, John M. (2008) Software for Data Analysis: Programming with R Springer. (For the R version.)
Chambers, John M. (1998) Programming with Data Springer (For the original S4 version.)
Classes for an overview of defining class, and
setOldClass
for the relation to S3 classes.
## using the definition of class "track" from \link{Classes}
## a new object with two slots specified
t1 <- new("track", x = seq_along(ydata), y = ydata)
# a new object including an object from a superclass, plus a slot
t2 <- new("trackCurve", t1, smooth = ysmooth)
### define a method for initialize, to ensure that new objects have
### equal-length x and y slots.
setMethod("initialize",
"track",
function(.Object, x = numeric(0), y = numeric(0)) {
if(nargs() > 1) {
if(length(x) != length(y))
stop("specified x and y of different lengths")
.Object@x <- x
.Object@y <- y
}
.Object
})
### the next example will cause an error (x will be numeric(0)),
### because we didn't build in defaults for x,
### although we could with a more elaborate method for initialize
try(new("track", y = sort(stats::rnorm(10))))
## a better way to implement the previous initialize method.
## Why? By using callNextMethod to call the default initialize method
## we don't inhibit classes that extend "track" from using the general
## form of the new() function. In the previous version, they could only
## use x and y as arguments to new, unless they wrote their own
## initialize method.
setMethod("initialize", "track", function(.Object, ...) {
.Object <- callNextMethod()
if(length(.Object@x) != length(.Object@y))
stop("specified x and y of different lengths")
.Object
})