R Inheritance - r - learn r - r programming

- One the most useful feature of an object oriented programming language is inheritance.
- Defining new classes out of existing ones.
- This is to say, we can derive new classes from existing base classes and adding new features.
- We don't have to write from scratch.
- Hence, inheritance provides reusability of code.
- Inheritance forms a hierarchy of class just like a family tree.
- Important thing to note is that the attributes define for a base class will automatically be present in the derived class.
- Moreover, the methods for the base class will work for the derived.

r programming inheritance

- Below, we discuss how inheritance is carried out for the three different class systems in R programming language.
Inheritance in S3 Class
- S3 classes do not have any fixed definition.
- Hence attributes of S3 objects can be arbitrary.
- Derived class, however, inherit the methods defined for base class.
- Let us suppose 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
}
- Furthermore, we have a method defined for generic function print() as follows.
print.student<- function(obj) {
cat(obj$name, "\n")
cat(obj$age, "years old\n")
cat("GPA:", obj$GPA, "\n")
}
- Now we want to create an object of class InternationalStudent which inherits from student.
- This is be done by assigning a character vector of class names like class(obj) <- c(child, parent).
Sample Code
># create a list
> s <- list(name="Deo", age=22, GPA=3.7, country="germany")
># make it of the class InternationalStudent which is derived from the class student
>class(s) <- c("InternationalStudent","student")
># print it out
> s
Output:
Deo
22years old
GPA: 3.7
- We can see above that, since we haven't 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")
}
- This will overwrite the method defined for class student as shown below.
> s
Deoisfromgermany
- We can check for inheritance with functions like inherits() or is().
> inherits(s,"student")
[1] TRUE
>is(s,"student")
[1] TRUE
Inheritance in S4 Class
- Since S4 classes have proper definition, derived classes will inherit both attributes and methods of the parent class.
- Let us 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 as shown below.
# inherit from student
setClass("InternationalStudent",
slots=list(country="character"),
contains="student"
)
- Here we have added an attribute country, rest will be inherited from the parent.
> s <- new("InternationalStudent",name="Deo", age=22, GPA=3.7, country="France")
> show(s)
Deo
22years old
GPA: 3.7
- We see that method define for class student got called when we did show(s).
- We can define methods for the derived class which will overwrite methods of the base class, like in the case of S3 systems.
Inheritance in Reference Class
- Inheritance in reference class is very much similar to that of the S4 class.
- We define in the contains argument, from which base class to derive from.
- Here is 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 dec_age() method 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 us put it to test.
> s <- InternationalStudent(name="Deo", age=22, GPA=3.7, country="germany")
>s$dec_age(5)
>s$age
[1] 16
>s$dec_age(20)
Errorins$dec_age(20) : Age cannot be negative
>s$age
[1] 16
- In this way, we are able to inherit from the parent class.