📜  R面向对象的编程

📅  最后修改于: 2021-01-08 09:47:41             🧑  作者: Mango

什么是R中的面向对象编程?

面向对象编程(OOP)是最流行的编程语言。借助oops概念,我们可以构建模块化的代码段,这些代码段用于为大型系统构建块。 R是一种功能语言,我们可以以oops风格进行编程。在R中,oops是管理大型程序复杂性的好工具。

在面向对象编程中,S3和S4是两个重要的系统。

S3

在oops中,S3用于重载任何函数。这样我们就可以使用不同的名称来调用函数,这取决于输入参数的类型或参数的数量。

S4

S4是oops的最重要特征。但是,这是一个限制,因为它很难调试。 S4有一个可选的参考类。

R中的对象和类

在R中,一切都是对象。因此,程序员在R中编写代码时将执行OOPS概念。对象是一种数据结构,具有一些可对其属性起作用的方法。

在R中,类是对象的轮廓或设计。类封装了数据成员以及函数。在R中,有两个最重要的类,即S3和S4,它们在执行OOP概念中起着重要的作用。

为了更好地理解,让我们一起讨论两个类及其示例。

1)S3课

借助S3类,我们可以利用实现通用功能OO的函数。此外,仅使用第一个参数,S3即可进行分派。 S3与实现Java OO传递消息的传统编程语言(例如Java,C++和C#)不同。这使S3易于实现。在S3类中,泛型函数调用该方法。 S3非常随意,没有正式的类定义。

S3几乎不需要程序员的知识。

创建一个S3类

在R中,我们定义了一个函数,该函数将创建一个类并返回所创建类的对象。由相关成员组成一个列表,确定列表的类,然后返回列表的副本。使用以下语法创建类

variable_name <- list(member1, member2, member3.........memberN)

s <- list(name = "Ram", age = 29, GPA = 4.0)
class(s) <- "Faculty"
s

输出量

定义通用函数print。

print
function(x, ...)
UseMethod("Print")

当我们执行或运行以上代码时,它将为我们提供以下输出:

类似于print函数,我们将使用通用函数GPA为GPA成员分配新值。通过以下方式,我们将使通用函数GPA

GPA <- function(obj1){
UseMethod("GPA")
}

创建通用函数GPA后,我们将为其实现默认函数

GPA.default <- function(obj){
cat("We are entering in generic function\n")
}

之后,我们将通过以下方式为GPA函数创建新方法

GPA.faculty <- function(obj1){
cat("Final GPA is ",obj1$GPA,"\n")
}

最后,我们将运行GPA方法为

GPA(s)

输出量

S3中的继承

继承是指将一个类的特征提取到另一个类中。在R的S3类中,继承是通过在向量中应用class属性来实现的。

对于继承,我们首先创建一个函数,该函数以以下方式创建班级教师的新对象

faculty<- function(n,a,g) {
value <- list(name=n, age=a, GPA=g)
attr(value, "class") <- "faculty"
value
}

之后,我们将定义通用函数print()的方法为

 print.student <- function(obj1) {
cat(1obj$name, "\n")
cat(1obj$age, "years old\n")
cat("GPA:", obj1$GPA, "\n")
}

现在,我们将创建一个国际班级的对象,该对象将从学院班级继承。通过将类名称的字符向量分配为:

class(Objet) <- c(child, parent)

所以,

# 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

当我们运行上面讨论的代码时,它将生成以下输出:

我们可以在上面看到,我们还没有定义任何形式的print方法。 InternationalFaculty(),该方法称为print.Faculty()。这种教学方法是继承的。

因此,我们的下一步是通过以下方式定义print.InternationalFaculty():

print.InternationalFaculty<- function(obj1) {
cat(obj1$name, "is from", obj1$country, "\n")
}

上面的函数将覆盖为班级教师定义的方法

Fac

getS3method和getAnywhere函数

R中使用了两个最常用和最受欢迎的S3方法函数。第一个方法是getS3method() ,第二个方法是getAnywhere()

S3找到与类关联的合适方法,这对于查看方法的实现方式很有用。有时,这些方法是不可见的,因为它们隐藏在名称空间中。我们使用getS3method或getAnywhere来解决此问题。

getS3方法

getAnywhere函数

getAnywhere("simpleloess")

2)S4课

S4类与S3类似,但比后者更正式。它与S3有两个不同的方面。首先,在S4中,有正式的类定义,提供了类的描述和表示。此外,它具有用于定义方法和泛型的特殊辅助功能。 S4还提供多个调度。这意味着通用函数能够采用基于多个基于类的参数的方法。

创建一个S4类

在R中,我们使用setClass()命令创建S4类。在S4类中,我们将指定一个用于验证数据一致性的函数,并指定默认值。在R中,成员变量称为插槽。

要创建S3类,我们必须定义该类及其插槽。按照以下步骤创建S4类

第1步:

第一步,我们将创建一个名为“教员”的新课程,其中包含三个插槽名称,年龄和GPA。

setClass("faculty", slots=list(name="character", age="numeric", GPA="numeric"))

setClass()函数还有许多其他可选参数,我们可以使用?setClass命令进行探索。

第2步:

在下一步中,我们将创建S4类的对象。 R提供new()函数来创建S4类的对象。在这个新函数,我们通过以下方式传递类名称和插槽值:

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

它将产生以下输出

使用生成器函数创建S4对象

setClass()函数返回一个生成器函数。此生成器函数有助于创建新对象。它充当构造函数。

A <- setClass("faculty", slots=list(name="character", age="numeric", GPA="numeric"))
A

它将生成以下输出:

现在,我们可以使用上面的构造函数创建新对象。构造函数依次使用new()函数创建对象。这只是一个环绕。让我们看一个示例,以了解如何借助generator 函数创建S4对象。

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)

输出量

S4类的继承

像S3类一样,我们也可以在S4类中执行继承。派生类将继承父类的属性和方法。让我们开始理解如何在S4类中执行继承。在S4类中有以下几种执行继承的方法:

第1步:

第一步,我们将通过以下方式创建或定义具有适当插槽的类:

setClass("faculty",
slots=list(name="character", age="numeric", GPA="numeric")
)

第2步:

在定义了类之后,我们的下一步是为display()泛型函数定义类方法。这将通过以下方式完成:

setMethod("show",
"faculty",
function(obj) {
cat(obj@name, "\n")
cat(obj@age, "years old\n")
cat("GPA:", obj@GPA, "\n")
}
)

第三步:

在下一步中,我们将使用参数contains定义派生类。派生类的定义如下

setClass("Internationalfaculty",
slots=list(country="character"),
contains="faculty"
)

在派生类中,我们仅定义了一个属性,即国家。其他属性将从其父类继承。

s <- new("Internationalfaculty",name="John", age=21, GPA=3.5, country="India")
show(s)

当我们进行表演时,为班级教师定义的方法将被调用。与S3系统一样,我们还可以为基类的派生类定义方法。