Object-Oriented Programming (OOP) is the most popular programming language. With the help of oops concepts, we can construct the modular pieces of code which are used to build blocks for large systems. R is a functional language, and we can do programming in oops style. In R, oops is a great tool to manage the complexity of larger programs.
In Object-Oriented Programming, S3 and S4 are the two important systems.
S3
In oops, the S3 is used to overload any function. So that we can call the functions with different names and it depends on the type of input parameter or the number of parameters.
S4
S4 is the most important characteristic of oops. However, this is a limitation, as it is quite difficult to debug. There is an optional reference class for S4.
Objects and Classes in R
In R, everything is an object. Therefore, programmers perform OOPS concept when they write code in R. An object is a data structure which has some methods that can act upon its attributes.
In R, classes are the outline or design for the object. Classes encapsulate the data members, along with the functions. In R, there are two most important classes, i.e., S3 and S4, which play an important role in performing OOPs concepts.
Let’s discuss both the classes one by one with their examples for better understanding.
1) S3 Class
With the help of the S3 class, we can take advantage of the ability to implement the generic function OO. Furthermore, using only the first argument, S3 is capable of dispatching. S3 differs from traditional programming languages such as Java, C ++, and C #, which implement OO passing messages. This makes S3 easy to implement. In the S3 class, the generic function calls the method. S3 is very casual and has no formal definition of classes.
S3 requires very little knowledge from the programmer.
Creating an S3 class
In R, we define a function which will create a class and return the object of the created class. A list is made with relevant members, class of the list is determined, and a copy of the list is returned. There is the following syntax to create a class
variable_name <- list(member1, member2, member3.........memberN)
Example
s <- list(name = "Ram", age = 29, GPA = 4.0) class(s) <- "Faculty" s
Output:
There is the following way in which we define our generic function print.
print function(x, ...) UseMethod("Print")
When we execute or run the above code, it will give us the following output:
Like print function, we will make a generic function GPA to assign a new value to our GPA member. In the following way we will make the generic function GPA
GPA <- function(obj1){ UseMethod("GPA") }
Once our generic function GPA is created, we will implement a default function for it
GPA.default <- function(obj){ cat("We are entering in generic function\n") }
After that we will make a new method for our GPA function in the following way
GPA.faculty <- function(obj1){ cat("Final GPA is ",obj1$GPA,"\n") }
And at last we will run the method GPA as
GPA(s)
Output:
Inheritance in S3
Inheritance means extracting the features of one class into another class. In the S3 class of R, inheritance is achieved by applying the class attribute in a vector.
For inheritance, we first create a function which creates new object of class faculty in the following way
faculty<- function(n,a,g) { value <- list(nname=n, aage=a, GPA=g) attr(value, "class") <- "faculty" value }
After that we will define a method for generic function print() as
print.student <- function(obj1) { cat(1obj$name, "\n") cat(1obj$age, "years old\n") cat("GPA:", obj1$GPA, "\n") }
Now, we will create an object of class InternationalFaculty which will inherit from faculty class. This process will be done by assigning a character vector of class name as:
class(Objet) <- c(child, parent)
so,
# create a list fac <- list(name="Shubham", age=22, GPA=3.5, country="India") # make it of the class InternationalFaculty which is derived from the class Faculty class(fac) <- c("InternationalFaculty","Faculty") # print it out fac
When we run the above code which we have discussed, it will generate the following output:
We can see above that, we have not defined any method of form print. InternationalFaculty (), the method called print.Faculty(). This method of class Faculty was inherited.
So our next step is to defined print.InternationalFaculty() in the following way:
print.InternationalFaculty<- function(obj1) { cat(obj1$name, "is from", obj1$country, "\n") }
The above function will overwrite the method defined for class faculty as
Fac
getS3method and getAnywhere function
There are the two most common and popular S3 method functions which are used in R. The first method is getS3method() and the second one is getAnywhere().
S3 finds the appropriate method associated with a class, and it is useful to see how a method is implemented. Sometimes, the methods are non-visible, because they are hidden in a namespace. We use getS3method or getAnywhere to solve this problem.
getS3method
getAnywhere function
getAnywhere("simpleloess")
2) S4 Class
The S4 class is similar to the S3 but is more formal than the latter one. It differs from S3 in two different ways. First, in S4, there are formal class definitions which provide a description and representation of classes. In addition, it has special auxiliary functions for defining methods and generics. The S4 also offers multiple dispatches. This means that common functions are capable of taking methods based on multiple arguments which are based on class.
Creating an S4 class
In R, we use setClass() command for creating S4 class. In S4 class, we will specify a function for verifying the data consistency and also specify the default value. In R, member variables are called slots.
To create an S3 class, we have to define the class and its slots. There are the following steps to create an S4 class
Step 1:
In the first step, we will create a new class called faculty with three slots name, age, and GPA.
setClass("faculty", slots=list(name="character", age="numeric", GPA="numeric"))
There are many other optional arguments of setClass() function which we can explore by using ?setClass command.
Step 2:
In the next step, we will create the object of S4 class. R provides new() function to create an object of S4 class. In this new function we pass the class name and the values for the slots in the following way:
setClass("faculty", slots=list(name="character", age="numeric", GPA="numeric")) # creating an object using new() # providing the class name and value for slots s <- new("faculty",name="Shubham", age=22, GPA=3.5) s
It will generate the following output
Creating S4 objects using a generator function
The setClass() function returns a generator function. This generator function helps in creating new objects. And it acts as a constructor.
A <- setClass("faculty", slots=list(name="character", age="numeric", GPA="numeric")) A
It will generate the following output:
Now we can use the above constructor function to create new objects. The constructor in turn uses the new() function to create objects. It is just a wrap around. Let’s see an example to understand how S4 object is created with the help of generator function.
Example
faculty<-setClass("faculty", slots=list(name="character", age="numeric", GPA="numeric")) # creating an object using generator() function # providing the class name and value for slots faculty(name="Shubham", age=22, GPA=3.5)
Inheritance in S4 class
Like S3 class, we can perform inheritance in S4 class also. The derived class will inherit both attributes and methods of the parent class. Let’s start understanding that how we can perform inheritance in S4 class. There are the following ways to perform inheritance in S4 class:
Step 1:
In the first step, we will create or define class with appropriate slots in the following way:
setClass("faculty", slots=list(name="character", age="numeric", GPA="numeric") )
Step 2:
After defining class, our next step is to define class method for the display() generic function. This will be done in the following manner:
setMethod("show", "faculty", function(obj) { cat(obj@name, "\n") cat(obj@age, "years old\n") cat("GPA:", obj@GPA, "\n") } )
Step 3:
In the next step, we will define the derived class with the argument contains. The derived class is defined in the following way
setClass("Internationalfaculty", slots=list(country="character"), contains="faculty" )
In our derived class we have defined only one attribute i.e. country. Other attributes will be inherited from its parent class.
s <- new("Internationalfaculty",name="John", age=21, GPA=3.5, country="India") show(s)
When we did show(s), the method defines for class faculty gets called. We can also define methods for the derived class of the base class as in the case of the S3 system.
Next Topic : Click Here