R开发(part10)--基于S3的面向对象编程
学习笔记,仅供参考,有错必纠
参考自:《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的面向对象编程相关推荐
- R开发(part12)--基于RC的面向对象编程
学习笔记,仅供参考,有错必纠 参考自:<R的极客理想>-- 张丹 文章目录 R开发 基于RC的面向对象编程 创建RC类和对象 对象赋值 定义对象的方法 RC对象内置方法和内置属性 RC类的 ...
- R开发(part11)--基于S4的面向对象编程
学习笔记,仅供参考,有错必纠 参考自:<R的极客理想>-- 张丹 文章目录 R开发 基于S4的面向对象编程 创建S4对象 访问S4对象的属性 S4的泛型函数 查看S4对象的函数 R开发 基 ...
- 基于MATLAB的面向对象编程(1)——类,属性,方法
这里写目录标题 1 入门 1.1 如何把面条抽象成Class 1.2 文件类 2 基于MATLAB的面向对象编程入门 2.1 如何定义一个类(Class) 2.2 创建一个对象 2.3 类的属性 2. ...
- 基于对象和面向对象编程范式辨析和主流编程语言中的应用
基于对象和面向对象编程范式辨析和主流编程语言中的应用 前言 本文的目的是想告诉大家,为什么C++的模板这么强大.为什么Ruby的Duck Typing(像鸭子那样编程)这么强大! 基于对象和面向对象编 ...
- R语言基于R6的面向对象编程
R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大. R语言作为统计学一门语言,一直在小众领域闪耀着光芒.直到大数据的爆发,R语言变成了一门炙手可 ...
- 基于MATLAB的面向对象编程(5)——对象的保存(save)和载入(load)
文章目录 6 MATLAB对象的保存和载入 6.1 save和load命令 对象的save和load操作 mat文件保存的对象内容. save过程和属性的默认值 保存handle类的对象要检查hand ...
- 基于MATLAB的面向对象编程(4)——类文件
文章目录 5 MATLAB的类文件的组织结构 5.1 如何使用其他文件夹中类的定义 5.2 类的定义和成员方法分开 5.3 类的局部函数 5.4 使用package文件夹管理类 5.5 类方法和函数重 ...
- mcem r语言代码_R语言面向对象编程:S3和R6
R语言面向对象编程:S3和R6 2017-06-10 0 R语言面向对象编程:S3和R6 一.基于S3的面向对象编程 基于S3的面向对象编程是一种基于泛型函数(generic function)的实现 ...
- 面向对象编程(一):类与对象 实训答案
面向对象编程(一):类与对象 实训答案 一.理解面向对象编程 1.下列关于面向对象编程的说法,正确的有:A.只要使用Java语言解决问题,就是在使用面向对象编程思想解决问题.B.对象是个体,从一组具有 ...
最新文章
- Asp.net Mvc Enum 扩展
- 团队项目-北航MOOC系统Android客户端 NABC
- 【C 语言】二级指针案例 ( 字符串切割 | 返回 自定义二级指针 作为结果 )
- 全国计算机一级在线模拟试题,全国计算机一级模拟试题及答案
- python爬虫机器_Python常用的机器学习库|python爬虫|python入门|python教程
- 如何在SAP S/4HANA Fiori UI上创建新的扩展字段
- java程序可分为两个基本文件_1 Java语言概述答案
- 设计图书馆oracle触发器,Oracle触发器开发与设计
- nginx学习笔记003---Nginx代理配置_注意,在Windows中路径要用/
- [HNOI2009] 有趣的数列
- 群接龙,JK上报一键化手机脚本autojs
- 【Linux环境下C语言编程】
- 用友-凭证打印行数如何调整
- 磊科路由器dns服务器老要修复,路由器DNS劫持的解决方法
- Vissim83D动态仿真
- Altium Designer使用技巧总结
- 接入商重构相关技术介绍
- 关于考试系统的ajax提交单个答案的压力测试
- PPT肘形箭头不好控制,画不出想要的弯曲箭头?
- 2019年SEOer必备黑科技浏览器插件——5118站长工具箱