Rev 42963 | Rev 46531 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
% File src/library/methods/man/setOldClass.Rd% Part of the R package, http://www.R-project.org% Copyright 1995-2007 R Core Development 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{density-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{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{ Specify Names for Old-Style Classes }\description{Register an old-style (a.k.a. \sQuote{S3}) class as a formally definedclass. The \code{Classes} argument is the character vector used as the\code{class} attribute; in particular, if there is more than onestring, old-style class inheritance is mimicked. Registering via\code{setOldClass} allows S3 classes to appear in methodsignatures, as a slot in an S4 class or as a superclass of an S4 class.}\usage{setOldClass(Classes, prototype, where, test = FALSE)}\arguments{\item{Classes}{A character vector, giving the names for old-styleclasses, as they would appear on the right side of an assignment ofthe \code{class} attribute in S3 computations.}\item{prototype}{An optional object to use as the prototype. This should be providedas the default S3 object for the class. If omitted, the S4 classcreated to register the S3 class is \code{VIRTUAL}. See thedetails.}\item{where}{Where to store the class definitions, the global or top-levelenvironment by default. (When either function is called in thesource for a package, the class definitions will be included in thepackage's environment by default.)}\item{test}{flag, if \code{TRUE}, inheritance must be testedexplicitly for each object, needed if the S3 class can have adifferent set of class strings, with the same first string.See the details below.}}\details{Each of the names will be defined as an S4 class, extending theremaining classes in \code{Classes}, and the class \code{oldClass},which is the \sQuote{root} of all old-style classes. S3 classes haveno formal definition, and therefore no formally defined slots. If a\code{prototype} argument is supplied in the call to\code{setOldClass()}, objects from the class can be generated, by acall to \code{\link{new}}; however, this usually not as relevant asgenerating objects from subclasses (see the section on extending S3classes below). If a prototype is not provided,the class will be created as a virtual S4class.The main disadvantage is that the prototype object in an S4 class thatuses this class as a slot will have a \code{NULL} object in that slot,which can sometimes lead to confusion.Beginning with version 2.8.0 of \R, support is provided for using a(registered) S3 class as a super class of a new S4 class. See thesection on extending S3 classes below, and the examples.See \link{Methods} for the details of method dispatch andinheritance.Some S3 classes cannot be represented as an ordinary combination of S4classes and superclasses, because objects from the S3 class can have avariable set of strings in the class. 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} once for each superclass.For example, ordered factors \emph{always} have the S3class \code{c("ordered", "factor")}. This is proper behavior, andmaps simply into two S4 classes, with \code{"ordered"} extending\code{"factor"}.But objects whose class attribute has \code{"POSIXt"} as the firststring may have either (or neither) of \code{"POSIXct"} or\code{"POSIXlt"} as the second string. This behavior can be mappedinto S4 classes but now to evaluate \code{is(x, "POSIXlt")}, forexample, requires checking the S3 class attribute on each object.Supplying the \code{test=TRUE} argument to \code{setOldClass} causesan explicit test to be included in the class definitions. It'snever wrong to have this test, but since it adds significantoverhead to methods defined for the inherited classes, you shouldonly supply this argument if it's known that object-specific testsare needed.The list \code{.OldClassesList} contains the old-style classes thatare defined by the methods package. Each element of the list is anold-style list, with multiple character strings if inheritance isincluded.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{Extending S3 Classes}{A call to \code{setOldClass} creates formal classes correspondingto S3 classes, allows these to be used as slots in other classes or ina signature in \code{\link{setMethod}}, and mimics the S3inheritance.In documentation for the initial implementation of S4 classes in \R,users were warned against defining S4 classes that contained S3classes, even if those had been registered. The warning was basedmainly on two points. 1) The S3 behavior of the objects would failbecause the S3 class would not be visible, for example, when S3methods are dispatched. 2) Because S3 classes have no formaldefinition, nothing can be asserted in general about the S3 part ofan object from such a class. (The warning was repeated as recentlyas the first reference below.)Nevertheless, defining S4 classes to contain an S3 class and extendits behavior is attractive in many applications. The alternative isto be stuck with S3 programming, without the flexibility and security offormal class and method definitions.Beginning with version 2.8.0, \R will provide support for extendingregistered S3 classes; that is, for new classes defined by a call to\code{\link{setClass}} in which the \code{contains=} argumentincludes an S3 class. See the examples below. The support is aimedprimarily at providing the S3 class information for all classes thatextend class \linkS4class{oldClass}, in particular by ensuring thatall objects from such classes contain the S3 class in a special slot.}\seealso{\code{\link{setClass}}, \code{\link{setMethod}}}\references{Chambers, John M. (2008)\emph{Software for Data Analysis: Programming with R}Springer. (For the R version: see section 10.6 for methodselection and section 13.4 for generic functions).Chambers, John M. (1998)\emph{Programming with Data}Springer (For the original S4 version.)}\examples{require(stats)setOldClass(c("mlm", "lm"))setGeneric("dfResidual", function(model)standardGeneric("dfResidual"))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)## two examples extending S3 class "lm", class "xlm" directly and "ylm" indirectlysetClass("xlm", representation(eps = "numeric"), contains = "lm")setClass("ylm", representation(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{setOldClass("data.frame", prototoype = data.frame())}}\keyword{ programming }\keyword{ methods }