学习笔记,仅供参考,有错必纠

参考自:《R的极客理想》-- 张丹


文章目录

  • R开发
    • 面向对象
      • 面向对象的R语言实现
      • 基于S3的面向对象编程
      • 泛型函数和方法调用
      • 查看S3对象的函数
      • S3对象的继承调用方式
      • S3对象的缺点

R开发

面向对象

R语言中有三种面向对象的编程实现,即S3类型、S4类型和RC类型。S3和S4都是基于泛型函数的,RC则是完全的面向对象实现。

面向对象的R语言实现

定义老师对象和行为,封装到teacher()泛型函数中;

定义同学对象和行为,封装到student()泛型函数中.

#定义老师对象和行为
teacher <- function(x, ...) UseMethod("teacher")
teacher.lecture <- function(x) print("讲课")
teacher.assignment <- function(x) print("布置作业")
teacher.correcting <- function(x) print("批改作业")
teacher.default<-function(x) print("你不是teacher")#定义同学对象和行为
student <- function(x, ...) UseMethod("student")
student.attend <- function(x) print("听课")
student.homework <- function(x) print("写作业")
student.exam <- function(x) print("考试")
student.default<-function(x) print("你不是student")#定义变量a和b
a <- "teacher"
b <- "student"attr(a, "class") <- "lecture"
attr(b, "class") <- "attend"teacher(a) #"讲课"
student(b) #"听课"#把老师和同学的行为都赋予到一个变量ab上
ab <- "teacher_student"
#分别设置不同对象的行为
attr(ab, "class") <- c("assignment", "homework")#执行老师的行为
teacher(ab) #"布置作业"
#执行同学的行为
student(ab) #"写作业"

基于S3的面向对象编程

在R语言中,基于S3对象的面向对象编程,是一种基于泛型函数的实现方式。泛型函数是一种特殊的函数,根据传入对象的类型决定调用哪个具体的方法。基于S3对象实现的面向对象编程,不同于其他语言的面向对象编程,是一种动态函数调用的模拟实现。。S3对象被广泛应用于R的早期的开发包中。

  • 通过变量创建S3对象

创建S3对象最简单的方法就是给一个变量增加class属性:

x <- 1
#定义为S3类型对象
attr(x, "class") <- "foo"
x
#输出start
[1] 1
attr(,"class")
[1] "foo"
#输出end
otype(x) #"S3"

也可以通过structure函数创建S3对象:

#创建S3类型对象
y <- structure(10, class = "foo")
y
#输出start
[1] 10
attr(,"class")
[1] "foo"
#输出end
otype(y) #"S3"
  • 创建多类型的S3对象

S3对象没有明确的结构关系,一个S3对象可以有多个类型。S3对象类型,通过变量的class属性来定义,class属性可以是一个向量,所以允许多类型:

z <- 5
attr(z, "class") <- c("foo", "bar")
class(z) #"foo" "bar"
otype(z) #"S3"

泛型函数和方法调用

对于S3对象的使用,通常用UseMethod函数来定义一个泛型函数的名称,通过传入参数的class属性来确定不同的方法调用:

#用UseMethod定义teacher泛型函数
teacher <- function(x, ...) UseMethod("teacher")
#函数检查teacher的类型
ftype(teach)
#用teacher.xxx的语法格式定义teacher对象的行为
teacher.lecture <- function(x) print("讲课")
teacher.correcting <- function(x) print("批改作业")#teacher.default定义默认行为
teacher.default<-function(x) print("teacher默认行为")

方法调用时,通过传入参数的class属性来确定不同的方法调用,比如,我们定义一个变量a,并设置a的class属性为lecture,将变量a传入teacher泛型函数中,teacher.lecture函数就会被调用:

a <- "teacherA"
attr(a, "class") <- "lecture"
#执行老师的行为
teacher(a)

当然,我们也可以直接调用teacher中定义的行为,如果这样做就失去了面向对象封装的意义:

teacher.lecture() #"讲课"
teacher.lecture(a) #"讲课"
teacher() #"teacher默认行为"

对比其他语言,这里R的泛型函数就表示方法接口,teacher.xxx表示接口的方法实现。

查看S3对象的函数

当我们使用S3对象进行面向对象封装后,可以用methods函数来查看S3对象中定义的内部行为函数:

#查看teacher对象
teacher
#输出start
function(x, ...) UseMethod("teacher")
<bytecode: 0x0000000015cbe690>
#输出end
#查看teacher对象的内部函数
methods(teacher)
#输出start
teacher.assignment teacher.correcting teacher.default teacher.lecture
#输出end

用getAnywhere函数查看函数:

#查看teacher.lecture
getAnywhere(teacher.lecture)
#输出start
A single object matching ‘teacher.lecture’ was found
It was found in the following places.GlobalEnvregistered S3 method for teacher
with valuefunction(x) print("讲课")
<bytecode: 0x0000000015c48b40>
#输出end
#查看不可见的函数predict.ppr
getAnywhere(predict.ppr)
#输出略

使用getS3method函数查看不可见的函数:

getS3method("predict", "ppr")
#输出略

S3对象的继承调用方式

S3对象可以用NextMethod函数来实现继承调用:

node <- function(x) UseMethod("node", x)
node.default <- function(x) print("默认node")
node.father <- function(x) c("father") #father函数
node.son <- function(x) c("son", NextMethod()) #son函数n1 <- structure(1, class = c("father"))
n2 <- structure(2, class = c("son", "father"))
node(n1) #"father"
node(n2) #"son"  "father"

通过对node函数传入n2的参数,node.son先被执行,然后通过NextMethod函数继续执行node.father函数。其实这样就模拟了子函数调用父函数的过程,实现面向对象编程中的继承。

S3对象的缺点

  • S3对象并不是完全的面向对象实现,而是一种通过函数调用来模拟面向对象实现.

  • S3使用起来简单,但在实际的面向对象编程过程中,当对象关系有一定的复杂度时,S3对象所表达的意义就会变得不太清楚.

  • S3封装的内部函数可绕过泛型函数的检查直接被调用.

  • S3参数的class属性可以被任意设置,没有预处理的检查.

  • S3参数只能通过调用class属性进行函数调用,其他属性则不会被class函数执行.

  • S3参数的class属性有多个值时,调用时会按照程序赋值顺序来调用第一个合法的函数.

R开发(part10)--基于S3的面向对象编程相关推荐

  1. R开发(part12)--基于RC的面向对象编程

    学习笔记,仅供参考,有错必纠 参考自:<R的极客理想>-- 张丹 文章目录 R开发 基于RC的面向对象编程 创建RC类和对象 对象赋值 定义对象的方法 RC对象内置方法和内置属性 RC类的 ...

  2. R开发(part11)--基于S4的面向对象编程

    学习笔记,仅供参考,有错必纠 参考自:<R的极客理想>-- 张丹 文章目录 R开发 基于S4的面向对象编程 创建S4对象 访问S4对象的属性 S4的泛型函数 查看S4对象的函数 R开发 基 ...

  3. 基于MATLAB的面向对象编程(1)——类,属性,方法

    这里写目录标题 1 入门 1.1 如何把面条抽象成Class 1.2 文件类 2 基于MATLAB的面向对象编程入门 2.1 如何定义一个类(Class) 2.2 创建一个对象 2.3 类的属性 2. ...

  4. 基于对象和面向对象编程范式辨析和主流编程语言中的应用

    基于对象和面向对象编程范式辨析和主流编程语言中的应用 前言 本文的目的是想告诉大家,为什么C++的模板这么强大.为什么Ruby的Duck Typing(像鸭子那样编程)这么强大! 基于对象和面向对象编 ...

  5. R语言基于R6的面向对象编程

    R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大. R语言作为统计学一门语言,一直在小众领域闪耀着光芒.直到大数据的爆发,R语言变成了一门炙手可 ...

  6. 基于MATLAB的面向对象编程(5)——对象的保存(save)和载入(load)

    文章目录 6 MATLAB对象的保存和载入 6.1 save和load命令 对象的save和load操作 mat文件保存的对象内容. save过程和属性的默认值 保存handle类的对象要检查hand ...

  7. 基于MATLAB的面向对象编程(4)——类文件

    文章目录 5 MATLAB的类文件的组织结构 5.1 如何使用其他文件夹中类的定义 5.2 类的定义和成员方法分开 5.3 类的局部函数 5.4 使用package文件夹管理类 5.5 类方法和函数重 ...

  8. mcem r语言代码_R语言面向对象编程:S3和R6

    R语言面向对象编程:S3和R6 2017-06-10 0 R语言面向对象编程:S3和R6 一.基于S3的面向对象编程 基于S3的面向对象编程是一种基于泛型函数(generic function)的实现 ...

  9. 面向对象编程(一):类与对象 实训答案

    面向对象编程(一):类与对象 实训答案 一.理解面向对象编程 1.下列关于面向对象编程的说法,正确的有:A.只要使用Java语言解决问题,就是在使用面向对象编程思想解决问题.B.对象是个体,从一组具有 ...

最新文章

  1. Asp.net Mvc Enum 扩展
  2. 团队项目-北航MOOC系统Android客户端 NABC
  3. 【C 语言】二级指针案例 ( 字符串切割 | 返回 自定义二级指针 作为结果 )
  4. 全国计算机一级在线模拟试题,全国计算机一级模拟试题及答案
  5. python爬虫机器_Python常用的机器学习库|python爬虫|python入门|python教程
  6. 如何在SAP S/4HANA Fiori UI上创建新的扩展字段
  7. java程序可分为两个基本文件_1 Java语言概述答案
  8. 设计图书馆oracle触发器,Oracle触发器开发与设计
  9. nginx学习笔记003---Nginx代理配置_注意,在Windows中路径要用/
  10. [HNOI2009] 有趣的数列
  11. 群接龙,JK上报一键化手机脚本autojs
  12. 【Linux环境下C语言编程】
  13. 用友-凭证打印行数如何调整
  14. 磊科路由器dns服务器老要修复,路由器DNS劫持的解决方法
  15. Vissim83D动态仿真
  16. Altium Designer使用技巧总结
  17. 接入商重构相关技术介绍
  18. 关于考试系统的ajax提交单个答案的压力测试
  19. PPT肘形箭头不好控制,画不出想要的弯曲箭头?
  20. 2019年SEOer必备黑科技浏览器插件——5118站长工具箱

热门文章

  1. C++ 大话数据结构 09: 中缀表达式 转后缀表达式 计算器
  2. 【数学基础】拉格朗日对偶
  3. 【机器学习】集成学习ensemble之随机森林
  4. 投屏连接台式计算机,笔记本如何连接一体电脑进行投屏?
  5. 小白自学深度学习——目录
  6. Airflow的SimpleHttpOperator不支持https问题解决
  7. OSI七层模型、数据封装与解封装过程、TCP三次握手、四次挥手
  8. 2.5 隐藏委托关系
  9. centos6.4下安装配置JDK+TOMCAT+MYSQL笔记
  10. 在项目中让Ajax面向对象 (二)