A further specification of an S3 class can be made if the
class is guaranteed to have some attributes of known class (where as
with slots, “known” means that the attribute is an object of
a specified class, or a subclass of that class).
In this case, the call to
setOldClass() can supply an S4 class
definition representing the known structure. Since S4 slots are
implemented as attributes (largely for just this reason), the known
attributes can be specified in the representation of the S4 class.
The usual technique will be to create an S4 class with the desired
structure, and then supply the class name or definition as the
See the definition of class
"ts" in the examples below and
data.frame example in Section 10.2 of the reference.
The call to
setClass to create the S4 class can use the same
class name, as here, so long as the call to
follows in the same package. For clarity it should be the next
expression in the same file.
In the example, we define
"ts" as a vector structure with a
numeric slot for
"tsp". The validity of this definition relies
on an assertion that all the S3 code for this class is consistent with
that definition; specifically, that all
"ts" objects will
behave as vector structures and will have a numeric
attribute. We believe this to be true of all the base code in R, but
as always with S3 classes, no guarantee is possible.
The S4 class definition can have virtual superclasses (as in
"ts" case) if the S3 class is asserted to behave
consistently with these (in the example, time-series objects are
asserted to be consistent with the '>structure class).
Failures of the S3 class to live up to its asserted
behavior will usually go uncorrected, since S3 classes inherently
have no definition, and the resulting invalid S4 objects can cause
all sorts of grief. Many S3 classes are not candidates for known
slots, either because the presence or class of the attributes are
not guaranteed (e.g.,
dimnames in arrays, although these are
not even S3 classes), or because the class uses named components of
a list rather than attributes (e.g.,
"lm"). An attribute
that is sometimes missing cannot be represented as a slot, not even
by pretending that it is present with class
attributes, unlike slots, can not have value
One irregularity that is usually tolerated, however, is to optionally
add other attributes to those guaranteed to exist (for example,
"data.frame" objects returned by
model.frame). Validity checks by
validObject ignore extra attributes; even if this check
is tightened in the future, classes extending S3 classes would likely
be exempted because extra attributes are so common.