Classes               package:methods               R Documentation

Class Definitions

Description:

     Class definitions are objects that contain the formal definition
     of a class of R objects, usually referred to as an S4 class, to
     distinguish them from the informal S3 classes. This document gives
     an overview of S4 classes; for details of the class representation
     objects, see help for the class 'classRepresentation'.

Metadata Information:

     When a class is defined, an object is stored that contains the
     information about that class.  The object, known as the _metadata_
     defining the class, is not stored under the name of the class (to
     allow programmers to write generating functions of that name), but
     under a specially constructed name. To examine the class
     definition, call 'getClass'.  The information in the metadata
     object includes:


     Slots: The data contained in an object from an S4 class is defined
          by the _slots_ in the class definition.

          Each slot in an object is a component of the object; like
          components (that is, elements) of a list, these may be
          extracted and set, using the function 'slot()' or more often
          the operator '"@"'.  However, they differ from list
          components in important ways. First, slots can only be
          referred to by name, not by position, and there is no partial
          matching of names as with list elements.

          All the objects from a particular class have the same set of
          slot names; specifically, the slot names that are contained
          in the class definition.  Each slot in each object always is
          an object of  the class specified for this slot in the
          definition of the current class. The word "is" corresponds to
          the R function of the same name ('is'), meaning that the
          class of the object in the slot must be the same as the class
          specified in the definition, or some class that extends the
          one in the definition (a _subclass_).

          One class name is special, '.Data'.  This stands for the
          'data part' of the object.  Any class that contains one of
          the basic object types in R, has implicitly a corresponding
          '.Data' slot of that type, allowing computations to extract
          or replace the data part while leaving other slots unchanged.
          The '.Data' slot also determines the type of the object; if
          'x' has a '.Data' slot, the type of the slot is the type of
          the object (that is, the value of 'typeof(x)'). Extending a
          basic type this way allows objects to use old-style code for
          the corresponding type as well as S4 methods.  Any basic type
          can be used for '.Data', with the exception of a few that do
          not behave like ordinary objects; namely, '"NULL"',
          environments, and external pointers.

          There is  one additional use of the data part, which is also
          an exception to the correspondence with the object's type. 
          The exception arises from the special treatment of 'matrix'
          and 'array' "classes" in R. Matrix and array objects are
          managed internally and recognized without regard to any class
          attribute; therefore, they can be used as the data part of a
          new class.  In this case, the object type for the new class
          depends on the type of the data in the matrix or array.

          If the new class does not have a data part as described
          above, the type of objects from the new class is '"S4"'.  


     Superclasses: The definition of a class includes the
          _superclasses_ -the classes that this class extends.  A class
          'Fancy', say, extends a class 'Simple' if an object from the
          'Fancy' class has all the capabilities of the 'Simple' class
          (and probably some more as well).  In particular, and very
          usefully, any method defined to work for a 'Simple' object
          can be applied to a 'Fancy' object as well.

          This relationship is expressed equivalently by saying that
          'Simple' is a superclass of 'Fancy', or that 'Fancy' is a
          subclass of 'Simple'.

          The direct superclasses of a class are those superclasses
          explicitly defined.   Direct superclasses can be defined in
          three ways.  Most commonly, the superclasses are listed in
          the 'contains=' argument in the call to 'setClass' that
          creates the subclass.   In this case the subclass will
          contain all the slots of the superclass, and the relation
          between the class is called _simple_, as it in fact is.
          Superclasses can also be defined explicitly by a call to
          'setIs'; in this case, the relation requires methods to be
          specified to go from subclass to superclass.   Thirdly, a
          class union is a superclass of all the members of the union. 
          In this case too the relation is simple, but notice that the
          relation is defined when the superclass is created, not when
          the subclass is created as with the 'contains=' mechanism.

          The definition of a superclass will also potentially contain
          its own direct superclasses.  These are considered (and
          shown) as superclasses at distance 2 from the original class;
          their direct superclasses are at distance 3, and so on.  All
          these are legitimate superclasses for purposes such as method
          selection.

          When superclasses are defined  by including the names of
          superclasses in the 'contains=' argument to 'setClass',   an
          object from the class will have all the slots defined for its
          own class _and_ all the slots defined for all its
          superclasses as well.

          The information about the relation between a class and a
          particular superclass is encoded as an object of class
          'SClassExtension'.  A list of such objects for the
          superclasses (and sometimes for the subclasses) is included
          in the metadata object defining the class.  If you need to
          compute with these objects (for example, to compare the
          distances), call the function 'extends' with argument
          'fullInfo=TRUE'.


     Prototype: The objects from a class, typically created by a call
          to 'new' or by assigning another object from the class, are
          defined by the _prototype_ object for the class and by
          additional arguments in the call to 'new', which are passed
          to a method for that class for the function 'initialize'.

          Each class definition contains a prototype object for the
          class.  This must have values for all the slots defined by
          the class definition. By default, these are the prototypes of
          all the slot classes, if those are not virtual classes. 
          However, the definition of the class can specify any valid
          object for any of the slots.


Virtual classes; Basic classes:

     Classes exist for which there are no actual objects, the _virtual_
     classes, in fact a very important programming tool.  They are used
     to group together ordinary classes that want to share some
     programming behavior, without necessarily restricting how the
     behavior is implemented. Virtual class definitions may if you want
     include slots (to provide some common behavior without fully
     defining the object-see the class 'traceable' for an example).

     A simple and useful form of virtual class is the _class union_, a
     virtual class that is defined in a call to 'setClassUnion' by
     listing one or more of subclasses (classes that extend the class
     union).  Class unions can include as subclasses basic data types
     (whose definition is otherwise sealed).

     There are a number of 'basic' classes, corresponding to the
     ordinary kinds of data occurring in R.  For example, '"numeric"'
     is a class corresponding to numeric vectors. The other vector
     basic classes are '"logical"', '"integer"',  '"complex"',
     '"character"',  '"raw"', '"list"' and '"expression"'. The
     prototypes for the vector classes are vectors of length 0 of the
     corresponding type.  Notice that basic classes are unusual in that
     the prototype object is from the class itself.

     In addition to the vector classes there are also basic classes
     corresponding to objects in the language, such as '"function"' and
     '"call"'. These classes are subclasses of the virtual class
     '"language"'. Finally, there are basic classes for specialized
     objects, such as '"environment"' and '"externalptr"'. The vector
     and language basic classes can be used as slots or as superclasses
     for any other class definitions.  The classes corresponding to
     other object types can be used as slots but not always as
     superclasses, since many of them do not follow the functional
     behavior of the language; in particular, they are not copied and
     so cannot have attributes or slots defined locally.

S3 Classes:

     Earlier, informal classes of objects (usually referred to as 'S3'
     classes) are used by many R functions.  It is natural to consider
     including them as the class for a slot in a formal class, or even
     as a class to be extended by the new class.  This isn't prohibited
     but there are some disadvantages, and if you do want to include S3
     classes, they should be declared by including them in a call to
     'setOldClass'.  Here are some considerations:


        *  Using S3 classes somewhat defeats the purpose of defining a
           formal class:  An important advantage to your users is that
           a formal class provides guarantees of what the object
           contains (minimally, the classes of the slots and therfore
           what data they contain; optionally, any other requirements
           imposed by a validity method).

           But there is no guarantee whatever about the data in an
           object from an S3 class.  It's entirely up to the functions
           that create or modify such objects.  If you want to provide
           guarantees to your users, you will need a valdity method
           that explicitly checks the contents of S3-class objects.

        *  To get the minimal guarantee (that the object in a slot has,
           or extends, the class for the slot) you should ensure that
           the S3 classes are known to _be_ S3 classes, possibly with S
           inheritance.  To do this, include a call to 'setOldClass'
           for the S3 classes used.

           Otherwise, the S3 class is undefined (and the code used by
           'setClass' will issue a warning).  Slot assignments, for
           example, will not then check for possible errors.

        *  Current versions of R (beginning with 2.8.0) try to
           accommodate S4 classes that extend S3 classes, that is,
           those including an S3 class in the 'contains=' argument to
           'setClass' . Specifically, objects from  such classes will
           contain the S3 class as a slot, and some S3 computations
           will recognize the S3 class, including method dispatch and
           the function 'inherits'.  See  'S3Class' for details. The S3
           classes _must_ have been registered by a call to 
           'setOldClass'. The basic caution remains true however: There
           is no guarantee that all S3 computations will be compatible,
           and some are known not to be.

        *  These caveats apply to S3 classes; that is, objects with a
           class assigned by some R function but without a formal class
           definition.  In contrast, the built-in vector types
           ('numeric', 'list', etc.) are generally fine as slots or for
           'contains=' classes.  These object types don't have formal
           slots, but the base code in the system essentially forces
           them to contain the type of data they claim to have.

           Objects with a "class"  of 'matrix' or 'array' are somewhat
           in between.  They do not have an explicit S3 class, but do
           have one or two attributes.  There is no general problem in
           having these as slots, but because there is no guarantee of
           a dimnames slot, they don't work as formal classes.  The
           'ts' class, although also ancient in the S language, is
           implemented in R essentially as an S3 class, with the
           implications noted above-not suitable for a 'contains='
           argument-but with a few S4 methods defined.  See the
           documentation for class 'structure' for more details.


References:

     Chambers, John M. (2008) _Software for Data Analysis: Programming
     with R_ Springer.  (For the R version.)

     Chambers, John M. (1998) _Programming with Data_ Springer (For the
     original S4 version.) 

     Chambers, John M.  and Hastie, Trevor  J. eds (1992) _Statistical
     Models in S._ Wadsworth & Brooks/Cole (Appendix A for S3 classes.)

     Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) _The New S
     Language_. Wadsworth & Brooks/Cole. (Out of print.) (The
     description of vectors, matrix, array and time-series objects.)

See Also:

     'Methods' for analogous discussion of methods, 'setClass' for
     details of specifying class definitions, 'is', 'as', 'new', 'slot'

