面向对象编程


2022年5月9日, Learn eTutorial
1967

在本教程中,您将探索 R 中的 OOPS 或面向对象概念。我们将从理解 R 中的函数式编程概念开始,以清晰地区分面向对象风格和函数式编程风格。R 中的一切都是具有不同属性和行为的对象。类和对象是与 OOPs 概念相关的首要工具,它们可以管理和维护 R 程序的复杂性。为了理解程序执行,R 程序分为两类:S3 类和 S4 类。因此,在本教程中,您将了解对象、类、s3 类和 s4 类,这些可以使 OOPs 成为更好或更强大的数据分析工具。

R 中的函数式编程是什么?

函数式编程风格主要用于 R 语言。也就是说,程序通过将某些函数 (f(x)) 应用于数据来启动,这些函数返回修改后的数据或应用函数到输入数据后的新数据。再次应用其他函数(如 (g(x)))来修改数据,依此类推,直到生成所需输出。

What is functional programming in R?

该图像代表将对象(参数 x)传递给函数 f(),以便在函数执行后返回一个值。
通常,编程始于函数式思维,假设您需要进行一些计算。您将为此创建一个函数,其中包含一组要执行的指令。此外,您还需要考虑要传递给函数的对象,即函数括号内的参数,例如 function(a,b),其中 a,b 构成参数。
 


Some calculations <-function(a,b){
//do something
return(result)
}

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

OOP 或面向对象编程是一种非常重要的编程风格或概念,与类和对象相关。除了这些主要概念之外,还有一些更核心的概念,如继承、多态、抽象、封装等。OOPs 概念用于 C++、JAVA、PYTHON 等语言。

在面向对象编程中,整个程序被细分为各种类,以简化对整个程序执行的理解。考虑一个简单的例子来理解 OOPs 概念。考虑人类被分为男性和女性。

面向对象编程是一种用于构建清晰的编程结构以管理、维护、调试和重用代码的技术。在面向对象编程(OOP)概念中,函数被称为方法。在 R 中,方法只是在面向对象环境中使用的函数。R 语言支持许多可用的对象类型,如数字、逻辑、字符、向量列表因子数据框。我们可以总结一下,R 中大约有 20 种或更多的可用对象类型。这些都是在 R 中进行数据分析所需的基本构建块。

对于面向对象编程,两个变量类型最重要:列表和环境。这两种变量类型(列表和环境)很重要,因为它们可以包含其他变量,并且对于创建更多其他复杂类型很有用。

面向对象编程对于数据分析来说不是必需的,甚至不是可取的。大多数情况下,数据存储在数据框中,并使用函数来操作数据框,最后返回另一个数据框。

注意:OOP 用于数量有限的复杂对象。

函数式编程与面向对象编程的区别

函数式编程 面向对象编程
定义 函数式编程是一种编程技术,专注于评估函数并开发计算机程序的结构和元素。 面向对象编程是一种编程范例,它使用抽象来创建基于现实世界的模型。
数据 使用不可变数据。 使用可变数据。
模型 遵循声明式编程模型。 遵循命令式编程模型。
支持 函数式编程支持并行编程 不支持函数式编程。
执行 按任何顺序执行 按特定顺序执行
迭代 使用递归 使用循环
主要单元 函数和变量 对象和方法

R 中的对象和类是什么?

在面向对象语言中,对象是一个具有某些属性和对其属性进行操作的方法的数据结构。R 中的一切都被视为对象。每个对象都有一个或多个属性。大多数 R 对象都有一个“类”属性。R 为统计编程提供了大量的类。R 中的一切都是对象,如列表、向量、数据框、因子、数组等。对象是与函数关联的数据成员的集合。对象是程序的基本构建块对象也是类的实例。从类创建对象的过程称为实例化。对象具有类、dimnames、names、dim、comments 等属性。对象具有实际存在性。

R 中的类

是对事物的描述,而对象是类的实例。通过提及对象的属性、行为以及与其他对象的关系来描述对象类型。术语方法可以描述为与指定对象类型相关联的函数。

类是对象的蓝图。例如,考虑房屋的草图,其中包含有关其地板、窗户、门、卧室、厨房等的所有详细信息,具体取决于房屋的建造模型。

让我们通过一个简单的例子来区分对象和类。考虑一个具有属性和功能的类 Person。

What are objects and classes in R?

属性(如姓名、年龄、职业、地点)的不同值会创建 Irina、John 和 Adam 等不同对象,但它们属于同一个类 Person。人的通用行为,如 walk()、eat()、sleep(),形成实现对象行为的方法。所以我们可以说类是负责为对象提供不同属性并提供不同方法来对这些属性执行操作的蓝图。

R 中有三个独立的面向对象系统。这三个系统如下:

  1. S3 类
  2. S4 类
  3. 引用类

每个系统独立于其他系统使用。鼓励新项目的开发者使用 s4 风格的类。它们广泛用于 Bioconductor 项目。许多开发者使用 S3 类,因为它们快速易用。

What is functional programming in R?

1. R 中的 S3 类

S3 执行一种称为泛函数 OO 的面向对象编程风格。这与大多数编程方言不同,例如 Java、C++ 和 C#,它们执行消息传递 OO。S3 本质上是原生的。S3 类的对象可以通过简单地添加类属性来创建。S3 类通过将函数划分为方法来支持函数重载。

如何定义和创建 S3 对象?

在 S3 对象中,您可以简单地创建一个列表。考虑下面的例子,其中创建了一个列表,其中包含 name、class、location 等列表元素。

如何定义和创建 S3 对象?


#Object Orientation in R

#How to define S3 class and create S3 objects ?

#Create a list with needed elements
 s3 = list(name = "Stephen", Standard = "x", age = 16, locati Canada")

print(s3)
 

输出


$name
[1] "Stephen"

$Standard
[1] "x"

创建了一个名为“Stephen”、标准为“x”、年龄为 16 岁、地点为“加拿大”的列表 s3。这些是列表 s3 的属性。下面的屏幕截图有助于您更好地理解属性,其中显示了一个用户数据对象。

S3 class in R

创建 S3 列表(即使用 name、standard、age、location 属性创建的列表)后,您可以使用 class 函数将该列表转换为 s3 对象。

如何定义和创建 S3 对象?


#Creates an object of class "student"
class(s3) = "student"

print(class(s3))
 

输出


[1] "student"

2. S4 类

S4 类是对 S3 类的改进。S4 类具有正式定义的结构,有助于创建在外观上或多或少相似的同一类对象。S4 类更标准化和结构化,并且更容易操作。

如何创建和操作 S4 对象?

使用 setClass() 函数定义 s4 类。在下面的示例中,代码定义了名为“student”的 s4 类,并且 slots 定义为一个列表,其中属性 name、standard、location 是字符类型,age 是数字类型。


setClass "student",slots=list(name="character",standard="character",age="numeric",locati))
 

创建或定义 S4 类后,使用 new() 创建一个特定的对象实例。在下面的代码中,s4 是使用 new() 创建的对象,其中类名是 student,slots 如 name、standard、age、location 已填入相应的值。


s  = new("student",name="Sen",standard="XI",age=17,locati)
 

整个程序执行后,返回以下输出,显示已创建 student 类对象,并且 slots 具有值,例如“name”是“Sen”,“standard”是“XI”等。


#Object Orientation in R

#How to define S4 class and create S4 objects ?

    #Create a list with needed elements
 setClass("student", slots = list(name = "character", standard = "character", age = "numeric", locati))
 s4 = new("student", name = "Sen", standard = "XI", age = 17, locati)
s4
 

输出


An object of class "student"
Slot "name":
[1] "Sen"

Slot "standard":
[1] "XI"

Slot "age":
[1] 17

Slot "location":
[1] "UK"

如何检查一个对象是 s4?

要检查一个对象是否为 s4,您可以使用 iss4() 函数。iss4() 函数返回一个布尔值,如果对象是 s4,则返回 TRUE,否则返回 FALSE,表示创建的对象不是 s4 类。让我们检查一下我们之前部分创建的对象 s4,它是一个 student 类的 s4 对象。


IsS4(s4)
 

代码一旦执行,就会返回 TRUE,因为它属于 s4 类。

当我们检查它是否是 s3 类对象时会发生什么?


isS4(s3)
[1] FALSE
 

如何访问和修改 S4 slot?

可以使用 @ 符号来访问 s4 中的组件或内容。对象类型 s4 后跟 @ 符号和要访问的组件名称。在下面的示例中,“name”是我们根据之前的示例创建的一个属性。


s4@name
 

这会返回“Sen”作为输出。

@ 符号也有助于设置或重置或为对象分配值。让我们使用赋值符号 (<-/=) 将名称“Sen”重置为“Peter”。


s4@name <- "Peter"
 

创建一个 student 类对象,其中新名称“Peter”取代了“Sen”,如下所示。


An object of class "student"
Slot "name":
[1] "Peter"

Slot "standard":
[1] "XI"

Slot "age":
[1] 17

Slot "location":
[1] "UK"

如何修改 S4 对象中的 slots?

slot() 函数允许修改 slots。slot() 函数包含对象名称和作为参数的属性(在括号内)。


slot(s4,"name")
 

代码返回“Peter”作为输出。您也可以使用 slot() 函数修改对象的值。


slot(s4,"name")="john"
 

输出


An object of class "student"
Slot "name":
[1] "john"

Slot "standard":
[1] "XI"

Slot "age":
[1] 17

OOP 中的引用类

引用类定义类似于定义 s4 类。在 s4 类中,使用 setClass() 进行定义,而引用类使用 setRefClass() 进行定义。类的变量成员需要包含在类定义中。在引用类中,成员变量称为字段,类似于 s4 类中的slots

定义引用类

下面的示例定义了具有字段的引用类 student。


setRefClass "student",fields=list(name="character",standard="character",age="numeric",locati
 

创建引用对象

setRefclass() 返回一个生成器函数,用于创建新对象。定义被存储到一个变量 Student。具有定义的 Student 变量构成了 student 类的生成器函数。


Student = setRefClass("student",fields=list(name="character",standard="character",age="numeric",locati

print(Student)
 

构成了 student 类的生成器函数。它提供了类字段、类方法等详细信息。


Generator for class "student":

Class fields:
                                              
Name:       name  standard       age  location
Class: character character   numeric character

Class Methods: 
     "field", "trace", "getRefClass", "initFields", "copy", "callSuper", ".objectPackage", "export", "untrace", 
     "getClass", "show", "usingMethods", ".objectParent", "import"

Reference Superclasses: 
     "envRefClass"

 

生成器函数是 student(),它创建具有字段值的新对象。


# now student() is our generator
function which can be used to create new objects
 s = student(name = "john", standard = "X", age = 15, locati
print(s)
 

代码执行后会给出以下输出。


Output:-
Reference class object of class "student"
Field "name":
[1] "John"

Field " standard ":
[1] "X"
Field " age ":
[1] 15
Field " location ":
[1] "UK"

如何访问和修改字段?

可以使用 $ 运算符访问对象的字段。


> s$name
[1] "John"
> s$age
[1] 15
> s$ location 
[1] "UK"

 

同样,它可以通过重新赋值来修改。


> s$name <- "Paul"
> s

 

重新赋值后的输出是:


Reference class object of class "student"
Field "name":
[1] "Paul"
Field " standard ":
[1] "X"
Field " age ":
[1] 15
Field " location ":
[1] "UK"

S3 类 S4 类 引用类
缺乏格式定义 使用 setclass() 定义的类 使用 setRefclass() 定义的类
通过设置类属性来创建对象。 使用 new() 创建对象 使用存储类的已定义生成器函数来创建对象。
使用 $ 访问属性 使用 @ 访问属性 使用 $ 访问属性
方法属于泛函数。 方法属于泛函数。 方法属于泛函数。
遵循按修改复制语义 遵循按修改复制语义 遵循按修改复制语义

何时应该在 R 中使用面向对象编程?

OOPS(面向对象编程)适用于对象数量有限且可以分析对象完整行为的情况。主要适用于行业特定的数据分析。考虑一个例子,有数千个生物分析包在 Bioconductor 项目中可用,特别是用于分析生物数据的基因组部分。Bioconductor 包使用基因组范围对象。在整个 Bioconductor 中重用这些对象,使得许多包的行为可预测。

另一个例子是通过 Web 应用程序编程接口 (API) 访问数据。当考虑此示例时,网站只能提供有限数量的响应。可以定义对象来存储这些响应。

考虑第三个例子 GUI 或图形用户界面。用于构建 GUI 的语言(如 JAVA 和 C#)是面向对象的。只需要考虑少数对象,例如按钮、复选框、文本框等。

从上述讨论的示例中可以看出,没有一个示例涉及任何数据分析。面向对象编程非常适合构建数据分析工具。我们可以这样总结:对于函数式编程,首先考虑函数,然后如何在数据中使用它们;而对于面向对象编程,您需要首先考虑数据结构,然后再考虑其功能。