Rev 63512 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
% File src/library/methods/man/setClass.Rd% Part of the R package, http://www.R-project.org% Copyright 1995-2013 R Core Team% Distributed under GPL 2 or later\name{setClass}\alias{setClass}\alias{classGeneratorFunction-class}\title{Create a Class Definition}\description{Create a class definition, specifying the representation (theslots) and/or the classes contained in this one (the superclasses),plus other optional details. As a side effect, the class definitionis stored in the specified environment. A generator functionis returned as the value of \code{setClass()}, suitable for creatingobjects from the class if the class is not virtual. Of the manyarguments to the function only \code{Class},\code{slots=} and \code{contains=} are usually needed.}\usage{setClass(Class, representation, prototype, contains=character(),validity, access, where, version, sealed, package,S3methods = FALSE, slots)}\arguments{\item{Class}{character string name for the class.}\item{slots}{ a named list or named character vector.The names are the names of the slots in the new class andthe elements are the character string names of thecorresponding classes.In rare cases where there is ambiguity about the class of a slot,because two classes of the same name are imported from differentpackages, the corresponding element of the argument must have a\code{"package"} attribute to disambiguate the choice.It is allowed to provide an unnamed character vector as a limitingcase, with the elements taken as slot names and all slots havingthe unrestricted class \code{"ANY"}.}\item{contains}{ the names (and optionally package slots) for the\emph{superclasses} of this class. The special superclass\code{"VIRTUAL"} causes the new class to be created as avirtual class; see the section on virtual classes in \link{Classes}.}\item{prototype}{ an object providing the defaultdata for the slots in this class. By default, each will be theprototype object for the superclass. If provided, using a call to\code{\link{prototype}} will carry out some checks. }\item{where}{ the environment in which to store the definition.Should not be supplied in standard use. For calls to\code{setClass()} appearing in the source code for a package, willdefault to the namespace of the package. For calls typed or sourcedat the top level in a session, will default to the global environment.}\item{validity}{ if supplied, should be a validity-checking methodfor objects from this class (a function that returns \code{TRUE} ifits argument is a valid object of this class and one or more stringsdescribing the failures otherwise). See \code{\link{validObject}}for details.}\item{S3methods, representation, access, version }{ All thesearguments are deprecated from version 3.0.0 of \R and should beavoided.\code{S3methods} is a flag indicating that old-style methodswill be written involving this class. Modern versions of \Rattempt to match formal and old-style methods consistently, sothis argument is largely irrelevant.\code{representation} is an argument inherited from S thatincluded both \code{slots} and \code{contains}, but the use ofthe latter two arguments is clearer and recommended.\code{access} and \code{version} are included forhistorical compatibility with S-Plus, but ignored.}\item{sealed}{ if \code{TRUE}, the class definition will be sealed,so that another call to \code{setClass} will fail on this class name.}\item{package}{ an optional package name for the class. Should veryrarely be used. By defaultthe name of the package in which the class definition is assigned.}}\value{A generator function suitable for creating objects from the class isreturned, invisibly. A call to this function generates a call to\code{\link{new}} for the class. The call takes any number of arguments,which will be passed on to the initialize method. If no\code{initialize} method is defined for the class or one of itssuperclasses, the default method expects named arguments with thename of one of the slots.Typically the generator function is assigned the name of the class,for programming clarity. This is not a requirement and objectsfrom the class can also be generated directly from\code{\link{new}}. The advantages of the generator function are aslightly simpler and clearer call, and that the call will containthe package name of the class (eliminating any ambiguity if twoclasses from different packages have the same name).If the class is virtual, an attempt to generate an object fromeither the generator or \code{new()}will result in an error.}\section{Basic Use: Slots and Inheritance}{The two essential arguments other than the class name are\code{slots} and \code{contains}, defining the explicit slotsand the inheritance (superclasses). Together, these arguments defineall the information in an object from this class; that is, the namesof all the slots and the classes required for each of them.The name of the class determineswhich methods apply directly to objects from this class. Theinheritance information specifies which methods apply indirectly,through inheritance. See \link{Methods}.The slots in a class definition will be the union of all the slotsspecified directly by \code{slots} and all the slots in allthe contained classes.There can only be one slot with a given name; specifically, thedirect and inherited slot names must be unique.That does not, however, prevent the same class from being inheritedvia more than one path.One kind of element in the \code{contains=} argument is special, specifying one of the \Robject types or one of a few other special \R types (\code{matrix} and\code{array}).See the section on inheriting from object types, below.Slot names \code{"class"} and \code{"Class"} are not allowed.There are other slot names with a special meaning; these names start withthe \code{"."} character. To be safe, you should define all ofyour own slots with names starting with an alphabetic character.}\section{Inheriting from Object Types}{In addition to containing other S4 classes, a class definition cancontain either an S3 class (see the next section) or a built-in R pseudo-class---oneof the \Robject types or one of the special \R pseudo-classes \code{"matrix"} and\code{"array"}.A class can contain at most one of the object types, directly or indirectly.When it does, that contained class determines the \dQuote{data part}of the class.Objects from the new class try to inherit the built inbehavior of the contained type.In the case of normal \R data types, including vectors, functions andexpressions, the implementation is relatively straightforward.For any object \code{x} from the class,\code{typeof(x)} will be the contained basic type; and a specialpseudo-slot, \code{.Data}, will be shown with the corresponding class.See the \code{"numWithId"} example below.Classes may also inherit from \code{"vector"}, \code{"matrix"} or\code{"array"}.The data part of these objects can be any vector data type.For an object from any class that does \emph{not} contain one of thesetypes or classes,\code{typeof(x)} will be \code{"S4"}.Some \R data types do not behave normally, in the sense that they arenon-local references or other objects that are not duplicated.Examples include those corresponding to classes \code{"environment"}, \code{"externalptr"}, and \code{"name"}.These can not be the types for objects with user-definedclasses (either S4 or S3) because setting an attribute overwrites theobject in all contexts.It is possible to define a class that inherits from such types,through an indirect mechanism that stores the inherited object in areserved slot.See theexample for class \code{"stampedEnv"} below.S3 method dispatch and the relevant \code{as.}\emph{type}\code{()}functions should behave correctly, but code that uses the type of theobject directly will not.Also, keep in mind that the object passed to low-level computationswill be the underlying object type, \emph{without} any of the slotsdefined in the class.To return the full information, you will usually have to define amethod that sets the data part.}\section{Inheriting from S3 Classes}{Old-style S3 classes have no formal definition. Objects are\dQuote{from} the class when their class attribute contains thecharacter string considered to be the class name.Using such classes with formal classes and methods is necessarily arisky business, since there are no guarantees about the content of theobjects or about consistency of inherited methods.Given that, it is still possible to define a class that inherits froman S3 class, providing that class has been registered as an old class(see \code{\link{setOldClass}}).Broadly speaking, both S3 and S4 method dispatch try to behavesensibly with respect to inheritance in either system.Given an S4 object, S3 method dispatch and the \code{\link{inherits}}function should use the S4 inheritance information.Given an S3 object, an S4 generic function will dispatch S4 methodsusing the S3 inheritance, provided that inheritance has been declared via\code{\link{setOldClass}}.}\section{Classes and Packages}{Class definitions normally belong to packages (but can be defined inthe global environment as well, by evaluating the expression on thecommand line or in a file sourced from the command line).The corresponding package name is part of the class definition; thatis, part of the \code{classRepresentation} object holding thatdefinition. Thus, two classes with the same name can exist indifferent packages, for most purposes.When a class name is supplied for a slot or a superclass in a call to\code{setClass}, acorresponding class definition will be found, looking from thenamespace of the current package, assuming the call in question appears directly in the source for thepackage, as it should to avoid ambiguity.The class definitionmust be found in the namespace of the current package, in the imports for thatnamespace or in the basic classes defined by the methods package.(The methods package must be included in the \code{Depends} directiveof the package's \code{"DESCRIPTION"} file in order for the\code{"CMD check"} utility to find these classes.)When this rule does not identify a class uniquely (because it appearsin more than one imported package) then the \code{\link{packageSlot}}of the character string name needs to be supplied with the name.This should be a rare occurrence.}\references{Chambers, John M. (2008)\emph{Software for Data Analysis: Programming with R}Springer. (For the R version.)Chambers, John M. (1998)\emph{Programming with Data}Springer (For the original S4 version.)}\seealso{\code{\link{Classes}} for a general discussion of classes,\code{\link{Methods}} for an analogous discussion of methods,\code{\link{makeClassRepresentation}}}\examples{\dontshow{if(isClass("trackMultiCurve")) removeClass("trackMultiCurve")if(isClass("trackCurve")) removeClass("trackCurve")if(isClass("track")) removeClass("track")}## A simple class with two slotstrack <- setClass("track",slots = c(x="numeric", y="numeric"))## an object from the classt1 <- track(x = 1:10, y = 1:10 + rnorm(10))## A class extending the previous, adding one more slottrackCurve <- setClass("trackCurve",slots = c(smooth = "numeric"),contains = "track")## an object containing a superclass objectt1s <- trackCurve(t1, smooth = 1:10)## A class similar to "trackCurve", but with different structure## allowing matrices for the "y" and "smooth" slotssetClass("trackMultiCurve",slots = c(x="numeric", y="matrix", smooth="matrix"),prototype = list(x=numeric(), y=matrix(0,0,0),smooth= matrix(0,0,0)))## See ?setIs for further examples using these classes## A class that extends the built-in data type "numeric"numWithId <- setClass("numWithId", slots = c(id = "character"),contains = "numeric")numWithId(1:3, id = "An Example")## inherit from reference object of type "environment"stampedEnv <-setClass("stampedEnv", contains = "environment",slots = c(update = "POSIXct"))setMethod("[[<-", c("stampedEnv", "character", "missing"),function(x, i, j, ..., value) {ev <- as(x, "environment")ev[[i]] <- value #update the object in the environmentx@update <- Sys.time() # and the update timex})e1 <- stampedEnv(update = Sys.time())e1[["noise"]] <- rnorm(10)\dontshow{tMC <- new("trackMultiCurve")is.matrix(slot(tMC, "y"))is.matrix(slot(tMC, "smooth"))setClass("myMatrix", "matrix", prototype = matrix(0,0,0))nrow(new("myMatrix")) # 0nrow(new("matrix")) # 1## simple test of prototype dataxxx <- stats::rnorm(3)setClass("xNum", slots = c(x = "numeric"), prototype = list(x = xxx))stopifnot(identical(new("xNum")@x, xxx))removeClass("xNum")removeClass("myMatrix")## The following should not be needed. But make check removes all files## between example files, in a crude way that does not cause the class## information to be reset. There seems no way to detect this, so we## have to remove classes ourselvesremoveClass("trackMultiCurve")removeClass("trackCurve")removeClass("track")}%dont show}\keyword{programming}\keyword{classes}\keyword{methods}