Menu
Coddy logo textTech

Defining S4 Classes

Part of the Object Oriented Programming section of Coddy's R journey. Lesson 22 of 57.

S4 is R's formal object system. setClass() declares a class with named slots and the type of each one, and new() creates an object. The @ operator reads a slot:

setClass("Person", slots = c(name = "character", age = "numeric"))
ada <- new("Person", name = "Ada", age = 36)
cat(ada@name, "is", ada@age)

Output:

Ada is 36

setClass() also returns a generator function. Assign it to a name, usually the class name, and call it like a constructor:

Person <- setClass("Person", slots = c(name = "character", age = "numeric"))
bo <- Person(name = "Bo", age = 7)
print(bo@age + 1)
print(is(bo, "Person"))

Output:

[1] 8
[1] TRUE

Unlike S3, R checks the slots. An unknown slot or a value of the wrong type stops new() with an error, so an S4 object always has the shape its class declares:

setClass("Person", slots = c(name = "character", age = "numeric"))
p <- new("Person", name = "Cy", age = "ten")

Output:

Error in validObject(.Object) : 
  invalid class “Person” object: invalid object for slot "age" in class "Person": got class "character", should be or extend class "numeric"
Calls: new -> initialize -> initialize -> validObject
Execution halted

A slot that is not given gets an empty value of its type, such as character(0). prototype sets real defaults instead. Older code declares the slots with representation(), which means the same as slots:

setClass("Task", slots = c(title = "character", done = "logical"),
         prototype = list(done = FALSE))
setClass("Note", representation(text = "character"))
t <- new("Task", title = "Write report")
print(t@done)
print(length(new("Note")@text))

Output:

[1] FALSE
[1] 0
challenge icon

Challenge

Easy

Declare the S4 class Book in Book.R with three slots: title and author of type character and pages of type numeric. Then complete book_label(b), which reads the slots with @ and returns Dune by Frank Herbert (412 pages).

The supplied code reads lines title;author;pages, creates each book with new("Book", ...), prints its label, and finally the slot names of the class.

Your code goes in Book.R. main.R holds the supplied input/output code and cannot be edited.

Try it yourself

source("Book.R")

# Supplied input/output code: keep it as it is
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, ";")[[1]]
  b <- new("Book", title = p[1], author = p[2], pages = as.numeric(p[3]))
  cat(book_label(b), "\n", sep = "")
}
cat("slots: ", paste(slotNames("Book"), collapse = ", "), "\n", sep = "")
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming

Practice on your own: Online R compiler