setClass: Create a Class Definition (2024)

setClassR Documentation

Description

Create a class definition and return a generator function to createobjects from the class. Typical usage will beof the style:

myClass <- setClass("myClass", slots= ...., contains =....)

where the first argument is the name of the new class and, if supplied, the arguments slots= and contains= specify the slotsin the new class and existing classes from which the new classshould inherit. Calls to setClass() are normally found in thesource of a package; when the package is loaded the class will bedefined in the package's namespace. Assigning the generatorfunction with the name of the class is convenient for users, butnot a requirement.

Usage

setClass(Class, representation, prototype, contains=character(), validity, access, where, version, sealed, package, S3methods = FALSE, slots)

Arguments

Class

character string name for the class.

slots

The names and classes for the slots in the new class. This argumentmust be supplied by name, slots=, in the call, for back compatibilitywith other arguments no longer recommended.

The argument must be vector with a names attribute, the names being those of the slots inthe new class. Each element of the vector specifies anexisting class; the corresponding slot must be from this classor a subclass of it. Usually, this is a character vectornaming the classes. It's also legal for the elements of thevector to be class representation objects, as returned by getClass.

As a limitingcase, the argument may be an unnamed charactervector; the elements are taken as slot names and all slots havethe unrestricted class "ANY".

contains

A vector specifying existing classes from whichthis class should inherit. The new class will have all the slotsof the superclasses, with the same requirements on the classesof these slots. This argumentmust be supplied by name, contains=, in the call, for back compatibilitywith other arguments no longer recommended.

See the section ‘Virtual Classes’ for the specialsuperclass "VIRTUAL".

prototype, where, validity, sealed, package

These arguments are currently allowed, but either they are unlikely to beuseful or there are modern alternatives that are preferred.

prototype: supplies an object with the defaultdata for the slots in this class. A more flexible approach is towrite a method for initialize().

where: supplies an environment in which to store the definition.Should not be used: For calls tosetClass() appearing in the source code for a package thedefinition will be stored in the namespace of the package.

validity: supplied a validity-checking methodfor objects from this class. For clearer code, use a separatecall to setValidity().

sealed: if TRUE, the class definition will be sealed,so that another call to setClass will fail on this classname. But the definition is automatically sealed after thenamespace is loaded, so explicit sealing it is not needed.

package: supplies an optional package name for the class, butthe class attribute should be the package in which the classdefinition is assigned, as it is by default.

representation, access, version, S3methods

All thesearguments are deprecated from version 3.0.0 of R and should beavoided.

representation is an argument inherited from S thatincluded both slots and contains, but the use ofthe latter two arguments is clearer and recommended.

access and version are included forhistorical compatibility with S-Plus, but ignored.

S3methods is a flag indicating that old-style methodswill be written involving this class; ignored now.

Value

A generator function suitable for creating objects from the class isreturned, invisibly. A call to this function generates a call tonew for the class. The call takes any number of arguments,which will be passed on to the initialize method. If noinitialize method is defined for the class or one of itssuperclasses, the default method expects named arguments with thename of one of the slots and unnamed arguments that are objects fromone of the contained classes.

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 fromnew. 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 new()will result in an error.

Basic Use: Slots and Inheritance

The two essential arguments other than the class name areslots and 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. Thesuperclass information specifies which methods apply indirectly,through inheritance. See Methods_Details for inheritance in methodselection.

The slots in a class definition will be the union of all the slotsspecified directly by slots and all the slots in allthe contained classes.There can only be one slot with a given name.A class may override the definition of a slot with a given name, butonly if the newly specified class is a subclass of theinherited one.For example, if the contained class had a slot a with class"ANY", then a subclass could specify a with class"numeric",but if the original specification for the slot was class"character", the new call to setClass would generate an error.

Slot names "class" and "Class" are not allowed.There are other slot names with a special meaning; these names start withthe "." character. To be safe, you should define all ofyour own slots with names starting with an alphabetic character.

Some inherited classes will be treated specially—object types, S3classes and a few special cases—whether inheriteddirectly or indirectly. See the next three sections.

Virtual Classes

Classes exist for which no actual objects can be created, thevirtual classes.

The most common and useful form of virtual class is the classunion, a virtual class that is defined in a call tosetClassUnion() rather than a call tosetClass().This call lists the members of the union—subclassesthat extend the new class.Methods that are written with the class union in the signatureare eligible for use with objects from any of the member classes.Classunions can include as members classes whosedefinition is otherwise sealed, including basic R data types.

Calls to setClass() will also create a virtual class,either when only the Class argument is supplied (no slotsor superclasses) or when the contains= argument includesthe special class name "VIRTUAL".

In the latter case, avirtual class may includeslots to provide some common behavior without fully definingthe object—see the class traceable for anexample.Note that "VIRTUAL" does not carry over to subclasses; aclass that contains a virtual class is not itself automatically virtual.

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 "matrix" and"array".A class can contain at most one of the object types, directly or indirectly.When it does, that contained class determines the “data part”of the class.This appears as a pseudo-slot, ".Data" and can be treated as aslot but actually determinesthe type of objects from this slot.

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 x from the class,typeof(x) will be the contained basic type; and a specialpseudo-slot, .Data, will be shown with the corresponding class.See the "numWithId" example below.

Classes may also inherit from "vector", "matrix" or"array".The data part of these objects can be any vector data type.

For an object from any class that does not contain one of thesetypes or classes,typeof(x) will be "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 "environment", "externalptr", and "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, ".xData".See theexample for class "stampedEnv" below.An object from such a class does not have a ".Data" pseudo-slot.

For most computations, these classes behave transparently as if theyinherited directly from the anomalous type.S3 method dispatch and the relevant as.type()functions should behave correctly, but code that uses the type of theobject directly will not.For example, as.environment(e1) would work as expected with the"stampedEnv" class, but typeof(e1) is "S4".

Inheriting from S3 Classes

Old-style S3 classes have no formal definition. Objects are“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 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 inheritsfunction 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 viasetOldClass. For details, see setOldClassand Section 10.8 of the reference.

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 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 tosetClass, 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 already defined in this package, in the imports directives ofthe package's DESCRIPTION andNAMESPACE files or in the basic classes defined by the methods package.(The ‘methods’ package must be included in the imports directivesfor any package that usesS4 methods and classes, to satisfy the"CMD check" utility.)

If a package imports two classes of the same name from separate packages, the packageSlotof the name argument needs to be set to the package name of theparticular class.This should be a rare occurrence.

References

Chambers, John M. (2016)Extending R,Chapman & Hall.(Chapters 9 and 10.)

See Also

Classes_Details for a general discussion of classes,Methods_Details for an analogous discussion of methods,makeClassRepresentation

Examples

## 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)))## 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 environment x@update <- Sys.time() # and the update time x})e1 <- stampedEnv(update = Sys.time())e1[["noise"]] <- rnorm(10)
setClass: Create a Class Definition (2024)

References

Top Articles
Latest Posts
Recommended Articles
Article information

Author: Errol Quitzon

Last Updated:

Views: 6474

Rating: 4.9 / 5 (79 voted)

Reviews: 86% of readers found this page helpful

Author information

Name: Errol Quitzon

Birthday: 1993-04-02

Address: 70604 Haley Lane, Port Weldonside, TN 99233-0942

Phone: +9665282866296

Job: Product Retail Agent

Hobby: Computer programming, Horseback riding, Hooping, Dance, Ice skating, Backpacking, Rafting

Introduction: My name is Errol Quitzon, I am a fair, cute, fancy, clean, attractive, sparkling, kind person who loves writing and wants to share my knowledge and understanding with you.