프로그램은 자료와 자료를 다루는 함수들을 조합해서 만든다. 자료와 함수 중 어느 쪽을 중시하느냐에 따라 객체지향 프로그래밍과 함수형 프로그래밍으로 나눌 수 있다. R은 함수형 프로그래밍 언어이지만 객체지향 프로그래밍 기법도 지원한다.
함수형 프로그래밍에서는 함수에 자료를 넘겨주지만, 객체지향 프로그래밍에서는 객체에 메시지를 전달하는 것으로 본다. 객체는 받은 메시지에 따라 자기 방법(method)대로 동작하는 것이다. 이런 방식은 print, summary, plot처럼 의미는 비슷하지만 객체에 따라 구체적인 동작이 다른 행동을 시킬 때 편리하다.
> circle <- function(r){
+ obj <- list(radius=r)
+ class(obj) <- 'circle'
+ obj
+ }
> rect <- function(w,h){
+ obj <- list(width=w,height=h)
+ class(obj) <- 'rect'
+ obj
+ }
> area.circle <- function(obj) pi * obj$radius^2
> area.rect <- function(obj) obj$width * obj$height
> area <- function(x) UseMethod('area')
> c <- circle(3)
> area(c)
[1] 28.27433
> r <- rect(4,5)
> area(r)
[1] 20
위의 예에서 circle은 원에 해당하는 객체를 생성하는 함수다. 먼저 반지름(radius)을 갖는 리스트를 만든 다음에 이 리스트가 'circle'이라는 범주(class)에 속하는 객체라고 지정해준다. rect는 직사각형에 해당하는 객체를 생성한다.
그 다음에 면적을 구하라는 메시지에 대해 각 범주의 객체들이 행동할 방법(method)을 지정해준다. 함수의 이름을 "메시지.범주"의 형태로 지어주기만 하면 된다. 방법을 나타내는 함수의 첫 매개변수는 메시지를 받을 객체가 되어야 한다.
UseMethod 함수는 객체에 메시지를 전달해서 해당하는 방법대로 작동하게 하는 기능을 한다. UseMethod는 원래 UseMethod(메시지, 객체, ...)의 형태로 사용하는데 객체를 명시해주지 않으면 UseMethod 함수가 속해있는 함수의 첫 매개변수(위의 경우엔 x)에 메시지를 보낸다.
print, plot, summary 등의 함수도 area와 비슷한 구조를 가지고 있다. print 메시지에 대응하는 방법을 한 번 만들어보자.
> print.circle <- function(obj) cat('A circle whose radius is',obj$r, '\n')
> c
A circle whose radius is 3
R에서는 객체의 이름을 그냥 입력하면 자동으로 print 함수를 적용해준다. print 함수는 "print"라는 메시지를 객체에 전달한다. circle 범주의 객체는 print.circle 함수에서 정해진 방법대로 화면에 출력된다.
methods 함수를 이용하면 어떤 종류의 방법들이 있는지 확인해볼 수 있다.
> methods('print')
[1] print.Arima*
[2] print.AsIs
[3] print.Bibtex*
...
[45] print.circle
...
> methods(class='circle')
[1] area.circle print.circle
[/code]