面向对象编程(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非常随意,没有正式的类定义。
在R中,我们定义了一个函数,该函数将创建一个类并返回所创建类的对象。由相关成员组成一个列表,确定列表的类,然后返回列表的副本。使用以下语法创建类
variable_name <- list(member1, member2, member3.........memberN)
示例
s <- list(name = "无涯教程", age = 29, GPA = 4.0)
class(s) <- "Faculty"
s
输出
我们可以通过以下方式定义通用函数打印。
print function(x, ...) UseMethod("Print")
当我们执行或运行上述代码时,它将为我们提供以下输出:
像打印函数一样,我们将使用通用函数GPA为GPA成员分配新值。通过以下方式,我们将使通用函数GPA
GPA <- function(obj1){
UseMethod("GPA")
}
创建通用函数GPA后,我们将为其实现默认函数
GPA.default <- function(obj){ cat("We are entering in generic function by learnfk\n") }
之后,我们将通过以下方式为GPA函数创建新方法
GPA.Faculty <- function(obj1){ cat("Final GPA is ",obj1$GPA,"\n") }
最后,我们将运行GPA方法为
GPA(s)
全部代码为
GPA <- function(obj1){ UseMethod("GPA") } GPA.default <- function(obj){ cat("We are entering in generic function\n") } GPA.Faculty <- function(obj1){ cat("Final GPA is ",obj1$GPA,"\n") } s <- list(name = "无涯教程", age = 29, GPA = 4.0) class(s) <- "Faculty" GPA(s)
输出
继承是指将一个类的特征提取到另一个类中。在R的S3类中,继承是通过在向量中应用class属性来实现的。
faculty<- function(n,a,g) {
value <- list(nname=n, aage=a, GPA=g)
attr(value, "class") <- "faculty"
value
}
之后,我们将定义通用函数print()的方法为
print.learnfk <- function(obj1) { cat(1obj$name, "\n") cat(1obj$age, "years old\n") cat("GPA:", obj1$GPA, "\n") }
现在,我们将创建一个InternationalFaculty类的对象,该对象将从faculty类继承。通过将类名称的字符向量分配为:
链接:https://www.learnfk.comhttps://www.learnfk.com/R/r-object-oriented-programming.html
来源:LearnFk无涯教程网
class(Objet) <- c(child, parent)
所以,
# 创建一个列表 fac <- list(name="Learnfk.com", age=22, GPA=3.5, country="China") # 使用派生自 Faculty 类的 InternationalFaculty 类 class(fac) <- c("InternationalFaculty","Faculty") # 打印出来 fac
当我们运行上面讨论的代码时,它将生成以下输出:
我们可以在上面看到,我们还没有定义任何表单打印方法。 InternationalFaculty(),该方法称为print.Faculty()。这种方法是继承的。
因此,我们的下一步是通过以下方式定义print.InternationalFaculty():
print.InternationalFaculty<- function(obj1) { cat(obj1$name, "is from", obj1$country, "\n") }
上面的函数将覆盖为班级老师定义的方法
# 创建一个列表 fac <- list(name="Learnfk.com", age=22, GPA=3.5, country="China") # 使用派生自 Faculty 类的 InternationalFaculty 类 class(fac) <- c("InternationalFaculty","Faculty") 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中,有正式的类定义,提供了类的描述和表示。此外,它具有用于定义方法和泛型的特殊辅助函数。
在R中,我们使用setClass()命令创建S4类。在S4类中,我们将指定一个用于验证数据一致性的函数,并指定默认值。在R中,成员变量称为插槽(slots)。
要创建S3类,我们必须定义该类及其插槽(slots)。按照以下步骤创建S4类
第一步,我们将创建一个名为"faculty"的新类,其中包含三个插槽(slots) name,age 和GPA。
setClass("faculty", slots=list(name="character", age="numeric", GPA="numeric"))
setClass()函数还有许多其他可选参数,我们可以使用setClass 命令进行查看。
在下一步中,我们将创建S4类的对象。 R提供new()函数来创建S4类的对象。在这个新函数中,我们通过以下方式传递类名和插槽值(slots):
setClass("faculty", slots=list(name="character", age="numeric", GPA="numeric")) #使用 new() 创建对象 # 提供插槽的类名和值 s <- new("faculty",name="Learnfk.com", 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"))
# 使用 generator() 函数创建对象
# 提供插槽的类名和值
faculty(name="Learnfk.com", age=22, GPA=3.5)
输出
像S3类一样,我们也可以在S4类中执行继承。派生类将继承父类的属性和方法。让我们开始理解如何在S4类中执行继承。在S4类中,有以下几种执行继承的方法:
第一步,我们将通过以下方式创建或定义具有适当插槽(slots)的类:
setClass("faculty", slots=list(name="character", age="numeric", GPA="numeric") )
在定义了类之后,我们的下一步是为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="无涯教程", age=21, GPA=3.5, country="CHINA")
show(s)
setClass("faculty",
slots=list(name="character", age="numeric", GPA="numeric")
)
setMethod("show",
"faculty",
function(obj) {
cat(obj@name, "\n")
cat(obj@age, "years old\n")
cat("GPA:", obj@GPA, "\n")
}
)
setClass("Internationalfaculty",
slots=list(country="character"),
contains="faculty"
)
s <- new("Internationalfaculty",name="无涯教程", age=21, GPA=3.5, country="CHINA")
show(s)
当我们进行表演时,为班级教师定义的方法将被调用。与S3系统一样,我们还可以为基类的派生类定义方法。
祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)