Rev 88547 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
% File src/library/methods/man/setOldClass.Rd% Part of the R package, https://www.R-project.org% Copyright 1995-2026 R Core Team% Distributed under GPL 2 or later\name{setOldClass}\alias{setOldClass}\alias{.setOldIs}\alias{POSIXct-class}\alias{POSIXlt-class}\alias{POSIXt-class}\alias{aov-class}\alias{maov-class}\alias{anova-class}\alias{anova.glm-class}\alias{anova.glm.null-class}\alias{Date-class}\alias{data.frame-class}\alias{data.frameRowLabels-class}\alias{density-class}\alias{difftime-class}\alias{dump.frames-class}\alias{factor-class}\alias{formula-class}\alias{glm-class}\alias{glm.null-class}\alias{hsearch-class}\alias{integrate-class}\alias{libraryIQR-class}\alias{lm-class}\alias{logLik-class}\alias{mlm-class}\alias{mtable-class}\alias{mts-class}\alias{ordered-class}\alias{packageIQR-class}\alias{packageInfo-class}\alias{recordedplot-class}\alias{rle-class}\alias{socket-class}\alias{summaryDefault-class}\alias{summary.table-class}\alias{oldClass-class}\alias{.OldClassesList}\alias{table-class}\alias{initialize,data.frame-method}\alias{initialize,factor-method}\alias{initialize,ordered-method}\alias{initialize,table-method}\alias{initialize,summary.table-method}\title{Register Old-Style (S3) Classes and Inheritance}\description{Register an old-style (a.k.a. \sQuote{S3}) class as a formally definedclass. Simple usage will be of the form:\code{setOldClass(Classes)}where \code{Classes} is the character vector that would be the\code{class} attribute of the S3 object. Calls to\code{setOldClass()} in the code for a packageallow the class to be used as a slot in formal (S4) classes and insignatures for methods (see \link{Methods_for_S3}).Formal classes can also contain a registered S3 class (see\link{S3Part} for details).If the S3 class has a known set of attributes, anequivalent S4 class can be specified by \code{S4Class=} in the call to\code{setOldClass()}; see the section \dQuote{Known Attributes}.}\usage{setOldClass(Classes, prototype, where, test = FALSE, S4Class)}\arguments{\item{Classes}{A character vector, giving the names for S3classes, as they would appear on the right side of an assignment ofthe \code{class} attribute in S3 computations.In addition to S3 classes, an object type or other valid data partcan be specified, if the S3 class is known to require its data tobe of that form.}\item{S4Class}{ optionally, the class definition or the class nameof an S4 class. The new class will have all the slots and otherproperties of this class, plus any S3 inheritance implied bymultiple names in the \code{Classes} argument. See the sectionon \dQuote{S3 classes with known attributes} below.}\item{prototype, where, test}{\emph{These arguments are currentlyallowed, but not recommended in typical applications.}\code{prototype}:An optional object to use as the prototype. If the S3 class isnot to be \code{VIRTUAL} (the default), the use of \code{S4Class=} ispreferred.\code{where}:Where to store the class definitions. Should be the default (thepackage namespace) for normal use in an application package.\code{test}: flag, if \code{TRUE}, arrange to test inheritanceexplicitly for each object, needed if the S3 class can have adifferent set of class strings, with the same first string.Such classes are inherently malformed, are rare, and should be avoided.}}\details{The name (or each of the names) in \code{Classes} will be defined as an S4 class, extending class \code{oldClass},which is the \sQuote{root} of all old-style classes. S3 classeswith multiple names in their class attribute will have acorresponding inheritance as formal classes. See the \code{"mlm"} example.S3 classes haveno formal definition, and therefore no formally defined slots.If no S4 class is supplied as a model, the class created will be avirtual class.If a virtual class (any virtual class) is used for a slot in another class, then theinitializing method for the class needs to put something legal inthat slot; otherwise it will be set to \code{NULL}.See \link{Methods_for_S3} for the details of method dispatch andinheritance with mixed S3 and S4 methods.Some S3 classes cannot be represented as an ordinary combination of S4classes and superclasses, because objects with the same initialstring in the class attribute can have different strings following.Such classes are fortunately rare. They violate the basic idea ofobject-oriented programming and should be avoided.If you must deal with them, it is still possible to registersuch classes as S4 classes, but now the inheritance has to be verifiedfor each object, and you must call \code{setOldClass} with argument\code{test=TRUE}.}\section{Pre-Defined Old Classes}{Many of the widely used S3 classes in the standard R distributioncome pre-defined for use with S4. These don't need to be explicitlydeclared in your package (although it does no harm to do so).The list \code{.OldClassesList} contains the old-style classes thatare defined by the methods package. Each element of the list is acharacter vector, with multiple strings if inheritance is included.Each element of the list was passed to \code{setOldClass} whencreating the \pkg{methods} package; therefore, these classes can be usedin \code{\link{setMethod}} calls, with the inheritance as implied bythe list.}\section{S3 Classes with known attributes}{A further specification of an S3 class can be made \emph{if} theclass is guaranteed to have some attributes of known class (where aswith slots, \dQuote{known} means that the attribute is an object ofa specified class, or a subclass of that class).In this case, the call to \code{setOldClass()} can supply an S4 classdefinition representing the known structure. Since S4 slots areimplemented as attributes (largely for just this reason), the knownattributes can be specified in the representation of the S4 class.The usual technique will be to create an S4 class with the desiredstructure, and then supply the class name or definition as theargument \code{S4Class=} to \code{setOldClass()}.See the definition of class \code{"ts"} in the examples below andthe \code{data.frame} example in Section 10.2 of the reference.The call to \code{\link{setClass}} to create the S4 class can use the sameclass name, as here, so long as the call to \code{setOldClass}follows in the same package. For clarity it should be the nextexpression in the same file.In the example, we define \code{"ts"} as a vector structure with anumeric slot for \code{"tsp"}. The validity of this definition relieson an assertion that all the S3 code for this class is consistent withthat definition; specifically, that all \code{"ts"} objects willbehave as vector structures and will have a numeric \code{"tsp"}attribute. We believe this to be true of all the base code in \R, butas always with S3 classes, no guarantee is possible.The S4 class definition can have virtual superclasses (as inthe \code{"ts"} case) if the S3 class is asserted to behaveconsistently with these (in the example, time-series objects areasserted to be consistent with the \linkS4class{structure} class).Failures of the S3 class to live up to its assertedbehavior will usually go uncorrected, since S3 classes inherentlyhave no definition, and the resulting invalid S4 objects can causeall sorts of grief. Many S3 classes are not candidates for knownslots, either because the presence or class of the attributes arenot guaranteed (e.g., \code{dimnames} in arrays, although these arenot even S3 classes), or because the class uses named components ofa list rather than attributes (e.g., \code{"lm"}). An attributethat is sometimes missing cannot be represented as a slot, not evenby pretending that it is present with class \code{"NULL"}, becauseattributes, unlike slots, can not have value \code{NULL}.One irregularity that is usually tolerated, however, is to optionallyadd other attributes to those guaranteed to exist (for example,\code{"terms"} in \code{"data.frame"} objects returned by\code{\link{model.frame}}). Validity checks by\code{\link{validObject}} ignore extra attributes; even if this checkis tightened in the future, classes extending S3 classes would likelybe exempted because extra attributes are so common.}\seealso{\code{\link{setClass}}, \code{\link{setMethod}}}\references{\bibinfo{R:Chambers:2016}{footer}{(Chapters 9 and 10, particularlySection 10.8)}\bibshow{R:Chambers:2016}}\examples{\dontshow{## All the predefined S3 classes with S4 versionssort(unlist(.OldClassesList))}require(stats)## "lm" and "mlm" are predefined; if they were not this would do it:\dontrun{setOldClass(c("mlm", "lm"))}## Define a new generic function to compute the residual degrees of freedomsetGeneric("dfResidual",function(model) stop(gettextf("This function only works for fitted model objects, not class \%s",class(model))))setMethod("dfResidual", "lm", function(model)model$df.residual)## dfResidual will work on mlm objects as well as lm objectsmyData <- data.frame(time = 1:10, y = (1:10)^.5)myLm <- lm(cbind(y, y^3) ~ time, myData)\dontshow{showClass("data.frame")# to see the predefined S4 "oldClass"}## two examples extending S3 class "lm": class "xlm" directly## and "ylm" indirectlysetClass("xlm", slots = c(eps = "numeric"), contains = "lm")setClass("ylm", slots = c(header = "character"), contains = "xlm")ym1 = new("ylm", myLm, header = "Example", eps = 0.)## for more examples, see ?\link{S3Class}.\dontshow{stopifnot(identical(dfResidual(myLm), myLm$df.residual))removeClass("ylm"); removeClass("xlm")rm(myData, myLm)removeGeneric("dfResidual")}\dontrun{## The code in R that defines "ts" as an S4 classsetClass("ts", contains = "structure", slots = c(tsp = "numeric"),prototype(NA, tsp = rep(1,3)))# prototype to be a legal S3 time-series## and now registers it as an S3 classsetOldClass("ts", S4Class = "ts", where = envir)}}\keyword{ programming }\keyword{ methods }