The R Project SVN R

Rev

Rev 88547 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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 }