R Inheritance
One the main concept of object oriented programming is inheritance which allows us to define a new class of existing classes. This means that we can derive new classes from existing base classes and adding new features. Hence, inheritance provides re-usability of code.
Inheritance in S3 class
Since S3 classes do not have any fixed definition. Hence attributes of S3 objects can be arbitrary. As we know, derived class inherits the methods defined for base class. For example, we have a function that creates new objects of class student as follows:student <- function(n,a,g) { value <- list(name=n, age=a, GPA=g) attr(value, "class") <- "student" value }And we have a method defined for generic function print() as follows:
print.student <- function(obj) { cat("Name:", obj$name, "\n") cat("Age:", obj$age, "years old\n") cat("GPA:", obj$GPA, "\n") }Now, we want to create an object of the class InternationalStudent which inherits from student. This is be done by assigning a character vector of class names like class(obj) <- c(child, parent).
Example:
# create a list s <- list(name="Nikita", age=21, GPA=8.5, country="France") # make it of the class InternationalStudent which is derived from the class student class(s) <- c("InternationalStudent","student") # print it out sOutput:
Name: Nikita Age: 21 years old GPA: 8.5From the above example we can see that, since we have not defined any method of the form print.InternationalStudent(), the method print.student() got called. This method of class student was inherited. Now, let us define print.InternationalStudent():
print.InternationalStudent <- function(obj) { cat(obj$name, "is from", obj$country, "\n") } sOutput:
Nikita is from France
Inheritance in S4 Class
Since S4 classes have proper definition, derived classes will inherit both attributes and methods of the parent class. Let’s define a class student with a method for the generic function show():# define a class called student setClass("student", slots=list(name="character", age="numeric", GPA="numeric") ) # define class method for the show() generic function setMethod("show", "student", function(object) { cat(object@name, "\n") cat(object@age, "years old\n") cat("GPA:", object@GPA, "\n") } )Inheritance is done during the derived class definition with the argument contains:
# inherit from student setClass("InternationalStudent", slots=list(country="character"), contains="student" )Here, new attribute is country; rest will be inherited from the parent.
s <- new("InternationalStudent",name="Nikita", age=24, GPA=8.5, country="France") show(s)Output:
Nikita 24 years old GPA: 8.5
Inheritance in Reference Class
It is similar to S4 class.Example:
Let’s see an example of student reference class with two methods inc_age() and dec_age().
student <- setRefClass("student", fields=list(name="character", age="numeric", GPA="numeric"), methods=list( inc_age = function(x) { age <<- age + x }, dec_age = function(x) { age <<- age - x } ) )Now we will inherit from this class. We also overwrite a method dec_age() to add an integrity check to make sure age is never negative.
InternationalStudent <- setRefClass("InternationalStudent", fields=list(country="character"), contains="student", methods=list( dec_age = function(x) { if((age - x)<0) stop("Age cannot be negative") age <<- age - x } ) )Let’s test it:
s <- InternationalStudent(name="Nikita", age=21, GPA=8.5, country="France") s$dec_age(5) s$age s$dec_age(20) s$ageOutput:
[1] 16 Error in s$dec_age(20) : Age cannot be negative [1] 16