S3面向对象系统
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 S3 system emphasize on generic functions and polymorphism. It's a function centric system which is different from 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
with the generic name and the object to dispatch on as its parameters.
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)
[ ] "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"
往期精彩