📅  最后修改于: 2021-01-08 09:47:41             🧑  作者: Mango
面向对象编程(OOP)是最流行的编程语言。借助oops概念,我们可以构建模块化的代码段,这些代码段用于为大型系统构建块。 R是一种功能语言,我们可以以oops风格进行编程。在R中,oops是管理大型程序复杂性的好工具。
在面向对象编程中,S3和S4是两个重要的系统。
S3
在oops中,S3用于重载任何函数。这样我们就可以使用不同的名称来调用函数,这取决于输入参数的类型或参数的数量。
S4
S4是oops的最重要特征。但是,这是一个限制,因为它很难调试。 S4有一个可选的参考类。
在R中,一切都是对象。因此,程序员在R中编写代码时将执行OOPS概念。对象是一种数据结构,具有一些可对其属性起作用的方法。
在R中,类是对象的轮廓或设计。类封装了数据成员以及函数。在R中,有两个最重要的类,即S3和S4,它们在执行OOP概念中起着重要的作用。
为了更好地理解,让我们一起讨论两个类及其示例。
借助S3类,我们可以利用实现通用功能OO的函数。此外,仅使用第一个参数,S3即可进行分派。 S3与实现Java OO传递消息的传统编程语言(例如Java,C++和C#)不同。这使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)
输出量
继承是指将一个类的特征提取到另一个类中。在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
R中使用了两个最常用和最受欢迎的S3方法函数。第一个方法是getS3method() ,第二个方法是getAnywhere() 。
S3找到与类关联的合适方法,这对于查看方法的实现方式很有用。有时,这些方法是不可见的,因为它们隐藏在名称空间中。我们使用getS3method或getAnywhere来解决此问题。
getS3方法
getAnywhere函数
getAnywhere("simpleloess")
S4类与S3类似,但比后者更正式。它与S3有两个不同的方面。首先,在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
它将产生以下输出
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)
输出量
像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系统一样,我们还可以为基类的派生类定义方法。