đ Introduction
Object-Oriented Programming (OOP) is a programming paradigm that organizes code into objects, which combine data (attributes) and functions (methods). R supports multiple object-oriented systems, each designed for different programming needs. The three primary OOP systems in R are S3, S4, and R6.
Information
đ¯ Why Learn Object-Oriented Programming?
- Organize code into reusable components.
- Improve code readability and maintainability.
- Model real-world entities as objects.
- Build scalable applications and packages.
- Create custom data structures and behaviors.
đ OOP Systems in R
đ Comparison of S3, S4, and R6
| Feature | S3 | S4 | R6 |
|---|---|---|---|
| Complexity | Simple. | Moderate. | Moderate. |
| Class Definition | Informal. | Formal. | Formal. |
| Type Checking | No. | Yes. | Yes. |
| Reference Semantics | No. | No. | Yes. |
| Common Usage | Base R objects. | Bioconductor and complex packages. | Applications and APIs. |
đĸ S3 Object System
S3 is the simplest object-oriented system in R. Classes are assigned using the class() function, and methods follow a naming convention.
Creating an S3 Object
Creating an S3 Object
student <- list(
name = "Alice",
marks = 92
)
class(student) <- "Student"
print(student)Creating an S3 Method
S3 Method
print.Student <- function(obj) {
cat(
"Student:",
obj$name,
"\nMarks:",
obj$marks
)
}
print(student)đĄ S4 Object System
S4 provides a formal class system with explicit definitions for slots (attributes), inheritance, and method dispatch.
Creating an S4 Class
Creating an S4 Class
setClass(
"Student",
slots = list(
name = "character",
marks = "numeric"
)
)Creating an S4 Object
Creating an S4 Object
student <- new(
"Student",
name = "Alice",
marks = 92
)
studentAccessing Slots
Accessing Slot Values
student@name
student@marksCreating an S4 Method
S4 Method
setMethod(
"show",
"Student",
function(object) {
cat(
"Name:",
object@name,
"\nMarks:",
object@marks
)
}
)
studentđĩ R6 Object System
R6 introduces reference-based objects. Unlike S3 and S4, modifying an R6 object changes the original object directly.
Installing and Loading R6
Install and Load R6
install.packages("R6")
library(R6)Creating an R6 Class
Creating an R6 Class
library(R6)
Student <- R6Class(
"Student",
public = list(
name = NULL,
marks = NULL,
initialize = function(
name,
marks
) {
self$name <- name
self$marks <- marks
},
display = function() {
cat(
"Name:",
self$name,
"\nMarks:",
self$marks
)
}
)
)Creating an R6 Object
Creating an R6 Object
student <- Student$new(
"Alice",
92
)
student$display()Updating Object Values
Modifying R6 Object
student$marks <- 95
student$display()đĻ Encapsulation in R6
R6 supports encapsulation by allowing both public and private members.
Private Members
Person <- R6Class(
"Person",
private = list(
age = 25
),
public = list(
showAge = function() {
print(
private$age
)
}
)
)
person <- Person$new()
person$showAge()đ§Ŧ Inheritance in R6
R6 classes can inherit properties and methods from other classes.
R6 Inheritance
Employee <- R6Class(
"Employee",
inherit = Student,
public = list(
salary = NULL,
initialize = function(
name,
marks,
salary
) {
super$initialize(
name,
marks
)
self$salary <- salary
}
)
)
employee <- Employee$new(
"Bob",
88,
60000
)
employee$display()đ Generic Functions in S3
Generic functions call different methods depending on the object's class.
Generic Function
describe <- function(x) {
UseMethod("describe")
}
describe.Student <- function(x) {
cat(
"Student:",
x$name
)
}
describe(student)đ S3 vs S4 vs R6 Example
| System | Object Creation |
|---|---|
| S3 | class(object) <- "Class" |
| S4 | new("Class") |
| R6 | Class$new() |
đ Real-World Example
A university management system stores student information. An R6 class can represent each student with attributes such as name and marks, along with methods to display and update information.
University Student Class
Student <- R6Class(
"Student",
public = list(
name = NULL,
marks = NULL,
initialize = function(
name,
marks
) {
self$name <- name
self$marks <- marks
},
updateMarks = function(
newMarks
) {
self$marks <- newMarks
},
display = function() {
cat(
"Student:",
self$name,
"\nMarks:",
self$marks
)
}
)
)
student <- Student$new(
"Sophia",
91
)
student$display()
student$updateMarks(95)
student$display()đ OOP Workflow
đ Common OOP Functions
| Function | Purpose |
|---|---|
| class() | Assigns or retrieves an S3 class. |
| UseMethod() | Creates S3 generic functions. |
| setClass() | Defines an S4 class. |
| new() | Creates an S4 object. |
| setMethod() | Defines an S4 method. |
| R6Class() | Creates an R6 class. |
| $new() | Creates an R6 object. |
â ī¸ Common Mistakes
| Mistake | Explanation | Solution |
|---|---|---|
| Using S3 when strict validation is required | S3 does not enforce attribute types. | Use S4 or R6 for formal class definitions. |
| Confusing S4 slot access with list access | S4 objects use @ instead of $. | Access slots using the @ operator. |
| Expecting copy behavior from R6 objects | R6 objects use reference semantics. | Remember that modifying one reference changes the original object. |
| Creating methods with incorrect naming in S3 | S3 dispatch depends on method names. | Follow the generic.class naming convention. |
đĄ Best Practices
- Use S3 for simple classes and lightweight extensions.
- Choose S4 when strict validation and formal class definitions are required.
- Use R6 for applications that require mutable objects and encapsulation.
- Keep methods focused on a single responsibility.
- Document class structures and methods for maintainability.
Best Practice
đ Summary
R supports three major object-oriented programming systems: S3, S4, and R6. S3 offers a simple and flexible approach using informal classes and generic functions. S4 introduces formal class definitions, slots, type checking, and structured method dispatch. R6 provides encapsulation, inheritance, and reference semantics similar to traditional object-oriented languages. Understanding these systems enables you to build reusable, maintainable, and scalable R programs while choosing the most suitable object model for your applications.