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 36setClass() 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] TRUEUnlike 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 haltedA 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] 0Challenge
EasyDeclare 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 = "")
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1S3 Basics
Working With FilesLists With a ClassConstructor FunctionsPrint and Format MethodsValidators and HelpersRecap - Temperatures4Encapsulation in R
Closures as ObjectsEnvironments as ObjectsAccessor FunctionsGuarding StateRecap - Parking Meter2S3 Generics and Methods
Generics and UseMethodDefault MethodsMethods for Base GenericsNextMethod BasicsRecap - Shape Areas8Reference Classes
Defining Reference ClassesMethods and Field UpdatesCopy SemanticsInheritance and callSuperRecap - Task Queue11Project: Library Management
Books and MembersBorrowing BooksPractice on your own: Online R compiler