15.4 Multiple classes

R objects can have multiple classes. Let’s say our student liam is not only a student, but also a human! We can simply append the extra class to the class attribute:

> class(liam) <- c("student", "human")

A human will have a print function, too. As all humans usually have names and an age (but not a field of study and grades, as students do), the print function will look different:

> print.human <- function(x, ...) {
+   output <- paste0("Hey! I'm a human called ", x$name, " and I'm ", x$age, " years old.")
+   print(output)
+ }

What will happen when we print liam? Which function will be called - the print function for students or the print function for humans? The answer is that R will simply go one by one through the elements in the vector of class attributes. It will first look for a print function in the class student, as this is the first class in the vector. If it does find a print function for students, R will call it and return. If for some reason, the class student does not have a print function, R will go to the second element in the vector. It will hence search for a print function for humans. If it does find one, R will call this one instead. Therefore, if we call print() on liam:

> print(liam)
[1] "Hello there! I'm a student. My name is Liam, I'm 25 years old and I study biology."

R still outputs the print.student() function, as student is the first class in the objects class vector. Now, let’s reverse the order of the class vector, such that human comes before student. You will see that R now calls the print.human() function:

> class(liam) <- rev(class(liam))
> print(liam)
[1] "Hey! I'm a human called Liam and I'm 25 years old."

If neither student nor human had a print() method, R would call print.default(), a special method written to handle general cases. We can quickly demonstrate this by removing the two print methods we’ve defined above from the environment. This can be done with the command rm():

> rm(print.student)
> rm(print.human)

R has forgotten about these functions. If we now call print() on our object, R will call the default print method:

> print(liam)
$name
[1] "Liam"

$age
[1] 25

$field
[1] "biology"

$grades
[1] 4.5 6.0 5.5

attr(,"class")
[1] "human"   "student"