| 42333 |
ripley |
1 |
% File src/library/methods/man/setOldClass.Rd
|
| 68948 |
ripley |
2 |
% Part of the R package, https://www.R-project.org
|
| 89602 |
maechler |
3 |
% Copyright 1995-2026 R Core Team
|
| 42333 |
ripley |
4 |
% Distributed under GPL 2 or later
|
|
|
5 |
|
| 21070 |
jmc |
6 |
\name{setOldClass}
|
| 56186 |
murdoch |
7 |
\alias{setOldClass}
|
| 25816 |
jmc |
8 |
\alias{.setOldIs}
|
| 21345 |
jmc |
9 |
\alias{POSIXct-class}
|
| 25816 |
jmc |
10 |
\alias{POSIXlt-class}
|
| 21345 |
jmc |
11 |
\alias{POSIXt-class}
|
| 25816 |
jmc |
12 |
\alias{aov-class}
|
|
|
13 |
\alias{maov-class}
|
| 21345 |
jmc |
14 |
\alias{anova-class}
|
|
|
15 |
\alias{anova.glm-class}
|
|
|
16 |
\alias{anova.glm.null-class}
|
| 46128 |
jmc |
17 |
\alias{Date-class}
|
| 21345 |
jmc |
18 |
\alias{data.frame-class}
|
| 46503 |
jmc |
19 |
\alias{data.frameRowLabels-class}
|
| 21345 |
jmc |
20 |
\alias{density-class}
|
| 89602 |
maechler |
21 |
\alias{difftime-class}
|
| 21345 |
jmc |
22 |
\alias{dump.frames-class}
|
|
|
23 |
\alias{factor-class}
|
|
|
24 |
\alias{formula-class}
|
|
|
25 |
\alias{glm-class}
|
|
|
26 |
\alias{glm.null-class}
|
|
|
27 |
\alias{hsearch-class}
|
|
|
28 |
\alias{integrate-class}
|
|
|
29 |
\alias{libraryIQR-class}
|
|
|
30 |
\alias{lm-class}
|
|
|
31 |
\alias{logLik-class}
|
|
|
32 |
\alias{mlm-class}
|
|
|
33 |
\alias{mtable-class}
|
|
|
34 |
\alias{mts-class}
|
|
|
35 |
\alias{ordered-class}
|
|
|
36 |
\alias{packageIQR-class}
|
|
|
37 |
\alias{packageInfo-class}
|
|
|
38 |
\alias{recordedplot-class}
|
|
|
39 |
\alias{rle-class}
|
|
|
40 |
\alias{socket-class}
|
| 51997 |
ripley |
41 |
\alias{summaryDefault-class}
|
| 21345 |
jmc |
42 |
\alias{summary.table-class}
|
|
|
43 |
\alias{oldClass-class}
|
|
|
44 |
\alias{.OldClassesList}
|
|
|
45 |
\alias{table-class}
|
| 37403 |
jmc |
46 |
\alias{initialize,data.frame-method}
|
|
|
47 |
\alias{initialize,factor-method}
|
|
|
48 |
\alias{initialize,ordered-method}
|
|
|
49 |
\alias{initialize,table-method}
|
|
|
50 |
\alias{initialize,summary.table-method}
|
| 51997 |
ripley |
51 |
\title{Register Old-Style (S3) Classes and Inheritance}
|
| 21070 |
jmc |
52 |
\description{
|
| 42761 |
ripley |
53 |
Register an old-style (a.k.a. \sQuote{S3}) class as a formally defined
|
| 71366 |
jmc |
54 |
class. Simple usage will be of the form:
|
|
|
55 |
|
|
|
56 |
\code{setOldClass(Classes)}
|
|
|
57 |
|
|
|
58 |
|
|
|
59 |
where \code{Classes} is the character vector that would be the
|
|
|
60 |
\code{class} attribute of the S3 object. Calls to
|
|
|
61 |
\code{setOldClass()} in the code for a package
|
| 71529 |
jmc |
62 |
allow the class to be used as a slot in formal (S4) classes and in
|
| 71366 |
jmc |
63 |
signatures for methods (see \link{Methods_for_S3}).
|
| 71529 |
jmc |
64 |
Formal classes can also contain a registered S3 class (see
|
|
|
65 |
\link{S3Part} for details).
|
| 71366 |
jmc |
66 |
|
|
|
67 |
If the S3 class has a known set of attributes, an
|
|
|
68 |
equivalent S4 class can be specified by \code{S4Class=} in the call to
|
| 71529 |
jmc |
69 |
\code{setOldClass()}; see the section \dQuote{Known Attributes}.
|
| 21070 |
jmc |
70 |
}
|
| 71366 |
jmc |
71 |
|
| 21070 |
jmc |
72 |
\usage{
|
| 46503 |
jmc |
73 |
setOldClass(Classes, prototype, where, test = FALSE, S4Class)
|
| 21070 |
jmc |
74 |
}
|
|
|
75 |
\arguments{
|
| 30666 |
ripley |
76 |
\item{Classes}{
|
| 49770 |
jmc |
77 |
A character vector, giving the names for S3
|
| 30666 |
ripley |
78 |
classes, as they would appear on the right side of an assignment of
|
| 46128 |
jmc |
79 |
the \code{class} attribute in S3 computations.
|
| 49770 |
jmc |
80 |
|
|
|
81 |
In addition to S3 classes, an object type or other valid data part
|
|
|
82 |
can be specified, if the S3 class is known to require its data to
|
|
|
83 |
be of that form.
|
| 30666 |
ripley |
84 |
}
|
| 71366 |
jmc |
85 |
\item{S4Class}{ optionally, the class definition or the class name
|
|
|
86 |
of an S4 class. The new class will have all the slots and other
|
|
|
87 |
properties of this class, plus any S3 inheritance implied by
|
|
|
88 |
multiple names in the \code{Classes} argument. See the section
|
|
|
89 |
on \dQuote{S3 classes with known attributes} below.
|
| 37403 |
jmc |
90 |
}
|
| 71366 |
jmc |
91 |
\item{prototype, where, test}{\emph{These arguments are currently
|
|
|
92 |
allowed, but not recommended in typical applications.}
|
|
|
93 |
|
|
|
94 |
\code{prototype}:
|
|
|
95 |
An optional object to use as the prototype. If the S3 class is
|
|
|
96 |
not to be \code{VIRTUAL} (the default), the use of \code{S4Class=} is
|
| 89602 |
maechler |
97 |
preferred.
|
|
|
98 |
|
| 71366 |
jmc |
99 |
\code{where}:
|
|
|
100 |
Where to store the class definitions. Should be the default (the
|
|
|
101 |
package namespace) for normal use in an application package.
|
| 89602 |
maechler |
102 |
|
| 71366 |
jmc |
103 |
\code{test}: flag, if \code{TRUE}, arrange to test inheritance
|
| 30666 |
ripley |
104 |
explicitly for each object, needed if the S3 class can have a
|
|
|
105 |
different set of class strings, with the same first string.
|
| 71366 |
jmc |
106 |
Such classes are inherently malformed, are rare, and should be avoided.
|
| 30666 |
ripley |
107 |
}
|
| 51997 |
ripley |
108 |
}
|
| 21070 |
jmc |
109 |
\details{
|
| 71366 |
jmc |
110 |
The name (or each of the names) in \code{Classes} will be defined as an S4 class, extending class \code{oldClass},
|
|
|
111 |
which is the \sQuote{root} of all old-style classes. S3 classes
|
|
|
112 |
with multiple names in their class attribute will have a
|
|
|
113 |
corresponding inheritance as formal classes. See the \code{"mlm"} example.
|
|
|
114 |
|
|
|
115 |
S3 classes have
|
|
|
116 |
no formal definition, and therefore no formally defined slots.
|
|
|
117 |
If no S4 class is supplied as a model, the class created will be a
|
|
|
118 |
virtual class.
|
| 71468 |
jmc |
119 |
If a virtual class (any virtual class) is used for a slot in another class, then the
|
|
|
120 |
initializing method for the class needs to put something legal in
|
|
|
121 |
that slot; otherwise it will be set to \code{NULL}.
|
| 37403 |
jmc |
122 |
|
| 71468 |
jmc |
123 |
See \link{Methods_for_S3} for the details of method dispatch and
|
| 71366 |
jmc |
124 |
inheritance with mixed S3 and S4 methods.
|
| 37403 |
jmc |
125 |
|
| 42963 |
ripley |
126 |
Some S3 classes cannot be represented as an ordinary combination of S4
|
| 71366 |
jmc |
127 |
classes and superclasses, because objects with the same initial
|
|
|
128 |
string in the class attribute can have different strings following.
|
|
|
129 |
Such classes are fortunately rare. They violate the basic idea of
|
|
|
130 |
object-oriented programming and should be avoided.
|
|
|
131 |
If you must deal with them, it is still possible to register
|
| 42963 |
ripley |
132 |
such classes as S4 classes, but now the inheritance has to be verified
|
|
|
133 |
for each object, and you must call \code{setOldClass} with argument
|
| 71468 |
jmc |
134 |
\code{test=TRUE}.
|
| 71366 |
jmc |
135 |
}
|
| 25816 |
jmc |
136 |
|
| 71366 |
jmc |
137 |
\section{Pre-Defined Old Classes}{
|
| 25816 |
jmc |
138 |
|
| 71366 |
jmc |
139 |
Many of the widely used S3 classes in the standard R distribution
|
|
|
140 |
come pre-defined for use with S4. These don't need to be explicitly
|
|
|
141 |
declared in your package (although it does no harm to do so).
|
| 89602 |
maechler |
142 |
|
| 30666 |
ripley |
143 |
The list \code{.OldClassesList} contains the old-style classes that
|
| 51213 |
maechler |
144 |
are defined by the methods package. Each element of the list is a
|
|
|
145 |
character vector, with multiple strings if inheritance is included.
|
| 21345 |
jmc |
146 |
Each element of the list was passed to \code{setOldClass} when
|
| 25118 |
hornik |
147 |
creating the \pkg{methods} package; therefore, these classes can be used
|
| 23678 |
jmc |
148 |
in \code{\link{setMethod}} calls, with the inheritance as implied by
|
|
|
149 |
the list.
|
| 21070 |
jmc |
150 |
}
|
|
|
151 |
|
| 46503 |
jmc |
152 |
\section{S3 Classes with known attributes}{
|
|
|
153 |
A further specification of an S3 class can be made \emph{if} the
|
|
|
154 |
class is guaranteed to have some attributes of known class (where as
|
|
|
155 |
with slots, \dQuote{known} means that the attribute is an object of
|
|
|
156 |
a specified class, or a subclass of that class).
|
|
|
157 |
|
|
|
158 |
In this case, the call to \code{setOldClass()} can supply an S4 class
|
|
|
159 |
definition representing the known structure. Since S4 slots are
|
| 71366 |
jmc |
160 |
implemented as attributes (largely for just this reason), the known
|
| 46503 |
jmc |
161 |
attributes can be specified in the representation of the S4 class.
|
|
|
162 |
The usual technique will be to create an S4 class with the desired
|
|
|
163 |
structure, and then supply the class name or definition as the
|
| 71366 |
jmc |
164 |
argument \code{S4Class=} to \code{setOldClass()}.
|
| 46503 |
jmc |
165 |
|
| 71366 |
jmc |
166 |
See the definition of class \code{"ts"} in the examples below and
|
|
|
167 |
the \code{data.frame} example in Section 10.2 of the reference.
|
|
|
168 |
The call to \code{\link{setClass}} to create the S4 class can use the same
|
|
|
169 |
class name, as here, so long as the call to \code{setOldClass}
|
|
|
170 |
follows in the same package. For clarity it should be the next
|
|
|
171 |
expression in the same file.
|
|
|
172 |
|
| 51997 |
ripley |
173 |
In the example, we define \code{"ts"} as a vector structure with a
|
|
|
174 |
numeric slot for \code{"tsp"}. The validity of this definition relies
|
|
|
175 |
on an assertion that all the S3 code for this class is consistent with
|
| 46503 |
jmc |
176 |
that definition; specifically, that all \code{"ts"} objects will
|
|
|
177 |
behave as vector structures and will have a numeric \code{"tsp"}
|
| 51997 |
ripley |
178 |
attribute. We believe this to be true of all the base code in \R, but
|
|
|
179 |
as always with S3 classes, no guarantee is possible.
|
| 46503 |
jmc |
180 |
|
|
|
181 |
The S4 class definition can have virtual superclasses (as in
|
|
|
182 |
the \code{"ts"} case) if the S3 class is asserted to behave
|
|
|
183 |
consistently with these (in the example, time-series objects are
|
|
|
184 |
asserted to be consistent with the \linkS4class{structure} class).
|
|
|
185 |
|
| 71366 |
jmc |
186 |
Failures of the S3 class to live up to its asserted
|
| 46503 |
jmc |
187 |
behavior will usually go uncorrected, since S3 classes inherently
|
|
|
188 |
have no definition, and the resulting invalid S4 objects can cause
|
|
|
189 |
all sorts of grief. Many S3 classes are not candidates for known
|
|
|
190 |
slots, either because the presence or class of the attributes are
|
|
|
191 |
not guaranteed (e.g., \code{dimnames} in arrays, although these are
|
|
|
192 |
not even S3 classes), or because the class uses named components of
|
|
|
193 |
a list rather than attributes (e.g., \code{"lm"}). An attribute
|
|
|
194 |
that is sometimes missing cannot be represented as a slot, not even
|
|
|
195 |
by pretending that it is present with class \code{"NULL"}, because
|
| 71366 |
jmc |
196 |
attributes, unlike slots, can not have value \code{NULL}.
|
| 46503 |
jmc |
197 |
|
| 51997 |
ripley |
198 |
One irregularity that is usually tolerated, however, is to optionally
|
|
|
199 |
add other attributes to those guaranteed to exist (for example,
|
|
|
200 |
\code{"terms"} in \code{"data.frame"} objects returned by
|
| 71366 |
jmc |
201 |
\code{\link{model.frame}}). Validity checks by
|
| 51997 |
ripley |
202 |
\code{\link{validObject}} ignore extra attributes; even if this check
|
|
|
203 |
is tightened in the future, classes extending S3 classes would likely
|
|
|
204 |
be exempted because extra attributes are so common.
|
|
|
205 |
}
|
| 46503 |
jmc |
206 |
|
| 21142 |
ripley |
207 |
\seealso{
|
|
|
208 |
\code{\link{setClass}}, \code{\link{setMethod}}
|
|
|
209 |
}
|
| 21070 |
jmc |
210 |
|
| 71366 |
jmc |
211 |
|
| 46128 |
jmc |
212 |
\references{
|
| 88547 |
hornik |
213 |
\bibinfo{R:Chambers:2016}{footer}{(Chapters 9 and 10, particularly
|
|
|
214 |
Section 10.8)}
|
|
|
215 |
\bibshow{R:Chambers:2016}
|
| 46128 |
jmc |
216 |
}
|
|
|
217 |
|
| 71366 |
jmc |
218 |
|
| 21070 |
jmc |
219 |
\examples{
|
| 71468 |
jmc |
220 |
\dontshow{
|
|
|
221 |
## All the predefined S3 classes with S4 versions
|
|
|
222 |
sort(unlist(.OldClassesList))
|
|
|
223 |
}
|
|
|
224 |
|
| 41508 |
ripley |
225 |
require(stats)
|
| 71468 |
jmc |
226 |
|
|
|
227 |
## "lm" and "mlm" are predefined; if they were not this would do it:
|
|
|
228 |
\dontrun{
|
|
|
229 |
setOldClass(c("mlm", "lm"))}
|
|
|
230 |
|
|
|
231 |
## Define a new generic function to compute the residual degrees of freedom
|
|
|
232 |
setGeneric("dfResidual",
|
|
|
233 |
function(model) stop(gettextf(
|
|
|
234 |
"This function only works for fitted model objects, not class \%s",
|
|
|
235 |
class(model))))
|
|
|
236 |
|
| 21142 |
ripley |
237 |
setMethod("dfResidual", "lm", function(model)model$df.residual)
|
| 21070 |
jmc |
238 |
|
| 21142 |
ripley |
239 |
## dfResidual will work on mlm objects as well as lm objects
|
|
|
240 |
myData <- data.frame(time = 1:10, y = (1:10)^.5)
|
|
|
241 |
myLm <- lm(cbind(y, y^3) ~ time, myData)
|
| 21070 |
jmc |
242 |
|
| 71468 |
jmc |
243 |
\dontshow{
|
| 51213 |
maechler |
244 |
showClass("data.frame")# to see the predefined S4 "oldClass"
|
| 71468 |
jmc |
245 |
}
|
| 51213 |
maechler |
246 |
|
| 71468 |
jmc |
247 |
## two examples extending S3 class "lm": class "xlm" directly
|
| 56287 |
ripley |
248 |
## and "ylm" indirectly
|
| 71228 |
maechler |
249 |
setClass("xlm", slots = c(eps = "numeric"), contains = "lm")
|
|
|
250 |
setClass("ylm", slots = c(header = "character"), contains = "xlm")
|
| 46128 |
jmc |
251 |
ym1 = new("ylm", myLm, header = "Example", eps = 0.)
|
|
|
252 |
## for more examples, see ?\link{S3Class}.
|
|
|
253 |
|
| 51213 |
maechler |
254 |
|
| 26000 |
ripley |
255 |
\dontshow{
|
| 46128 |
jmc |
256 |
stopifnot(identical(dfResidual(myLm), myLm$df.residual))
|
|
|
257 |
removeClass("ylm"); removeClass("xlm")
|
| 21142 |
ripley |
258 |
rm(myData, myLm)
|
| 46128 |
jmc |
259 |
removeGeneric("dfResidual")}
|
| 37403 |
jmc |
260 |
|
| 46503 |
jmc |
261 |
\dontrun{
|
|
|
262 |
## The code in R that defines "ts" as an S4 class
|
| 71228 |
maechler |
263 |
setClass("ts", contains = "structure", slots = c(tsp = "numeric"),
|
|
|
264 |
prototype(NA, tsp = rep(1,3)))
|
|
|
265 |
# prototype to be a legal S3 time-series
|
| 46503 |
jmc |
266 |
## and now registers it as an S3 class
|
| 71228 |
maechler |
267 |
setOldClass("ts", S4Class = "ts", where = envir)
|
| 51213 |
maechler |
268 |
}
|
| 46503 |
jmc |
269 |
|
|
|
270 |
}
|
| 21070 |
jmc |
271 |
\keyword{ programming }
|
|
|
272 |
\keyword{ methods }
|