Skip to content
hadley edited this page Oct 18, 2010 · 24 revisions

The S4 object system

Compared to S3, the S4 object system is much stricter, and much closer to other OO systems. I recommend you familiarise yourself with the way that S3 works before reading this document - many of underlying ideas are the same, but the implementation is much stricter.

There are two major differences from S3:

  • multiple dispatch: the generic function can be dispatched to a method based on the class of any number of argument, not just one

  • formal class definitions: unlike S3, S4 formally defines the representation and inheritance for each class

Here we introduce the basics of S4, trying to stay away from the esoterica and focussing on the ideas that you need to understand and write the majority of S4 code. If you would like to learn more, consult one of the more detailed resources such as: ...

Defining classes

In S3, you can turn any object into an object of a particular class just by setting the class attribute. S4 is much stricter: you must define the representation of the call using setClass, and the only way to create it is through the constructer function new.

A class has two key properties:

  • representation: a list of slots (or attributes), giving their names and classes. For example, a person class might be represented a character name and a numeric age, as follows: representation(name = "character", age = "numeric")

  • a character vector of classes that it inherits from, or in S4 terminology, contains

    setClass(name, representation, prototype, contains)

    new(name, values) initialize

Can also define an optional method that applies additional restrictions. This function can also be specified in setClass.

setValidity()

Accessing slots:

@
getSlot
getSlots

There's some tension between the usual interactive functional style of R and the global side-effect causing S4 class definitions. In most programming languages, class definition occurs at compile-time, while object instantiation occurs at run-time - it's unusual to be able to create new classes interactively. In particular, note that multiple calls to setClass with the same class name will silently override the previous definition unless the first definition is sealed with sealed = TRUE.

Defining methods

Generic functions and methods work similarly to S3, but dispatch is based on the class of all arguments, and there is a special syntax for creating both generic functions and new methods.

setGeneric(name, definition)
setMethod(method_name, signature, definition)

Inheritance

  • callNextMethod
  • inheritance
  • setIs

Common methods

  • is, as as<-
Clone this wiki locally