The S3 OOP system

October 15, 2010
By

(This article was first published on YGC » R, and kindly contributed to R-bloggers)

R currently supports two internal OOP systems (S3 and S4), and several others as add-on packages, such as R.oo, and OOP.

S3 is easy to use but not reliable enough for large software projects. The emphasis of the S3 system was on generic functions and polymorphism. It’s a function centric system which is different to class centric system like JAVA.

Computations are carried out by methods. In many OOP languages, that is, a call to obj.method() which will find the first ancestor class of obj that has a method .method(). R makes the same dicision in a different way, it turns the idea of inheritance “inside out”. In R, a special type of function called generic function decides which method to invoke. Methods are defined in the same way as a normal function, but with a tag describing what type of object they were designed to process.

Object Class

The class of an object is defined by a character vector of class names.

> x <- 1
> class(x) <- "foo"
#or
> attr(x, "class") <- "foo"
#or
> x <- structure(1, class="foo")
> x
[1] 1
attr(,"class")
[1] "foo"

Objects can have many classes:

> class(x) <- c("foo", "bar")
> x
[1] 1
attr(,"class")
[1] "foo" "bar"

Generic functions and method dispatch

A generic function is a function that examines the class of its first argument, and thus decides which specific method to dispatch to.

Generic functions are defined by UseMethod which names the generic name and the object to dispatch on.

The following example shows how to define a generic function:

sound <- function(x) UseMethod("sound", x)

Methods are defined with a naming convention: generic.class:

sound.dog <- function(x) "bark"
sound.cow <- function(x) "moo"
sound.default <- function(x) "animal sound"

The methods function can find out which classes a generic function was designed for.

> methods("sound")
[1] sound.cow     sound.default sound.dog

R looks for methods in the order in which they appear in the class vector until it found the appropriate method to operate on.

> x <- structure("cat", class = c("cat", "dog", "cow"))
> sound(x)
[1] "bark"

Inheritance

In S3 system, evaluation may be passed to a less specific method by calling NextMethod which provide a simple inheritance mechanism. NextMethod will dispatch on the second element of the class vector:

> class(x) <- c("dog", "cow")
> sound(x)
[1] "bark"
> sound.dog <- function(x) NextMethod()
> sound(x)
[1] "moo"

Related Posts

To leave a comment for the author, please follow the link and comment on his blog: YGC » R.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...



If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Tags: , , ,

Comments are closed.