关于R的S3类S4类

关于类:

说到类,每门编程语言好像都可以定义类吧?至少不要定义得不伦不类!!!
最近学习S3,S4类,与大家分享一些自己的心得体会,也欢迎各位在下方留言批评指正

关于面向对象

这是一种面向对象编程方式,什么是面向对象呢?这里不得不提到面向对象的三个特征:封装,继承,多态。
1.封装:简单说就是把你定义的对象封装到一个类里面(集中管理,好听候调遣)
2.继承:定义类与类之间的关系,子类享有父类的数据结构和方法机制。继承类无需再重新定义类
3.多态:由继承产生的子类,对同一操作(指令)会产生不同的相应

R语言S3类

R语言面向对象编程是基于泛型函数的,好像是没有严格的类的结构。而S3类由list构成,list里面的内容即我们说的属性。
上代码:

dnaseq = list(seq = "ATGC",length = nchar("ATGC"))
dnaseq

$seq
[1] "ATGC"

$length
[1] 4

S3类可以通过$来访问类的属性


访问

那么这个类就已经创建好了,我们还可以继续添加类名

class(dnaseq) = append(class(dnaseq),"DNAseq")
class(dnaseq)
[1] "list"   "DNAseq"

如何创建类,一般的话我们可以写个函数,自动往里面添加,多的不说,上代码

DNAseq <- function(seq = "ATGCATGCATGCATGCATGC"){ 
  me <- list( seq = seq, length = nchar(seq) ) # 给类取名
  class(me) <- append(class(me), "DNAseq")  #添加类名
  return(me)
}

#seq作为变量,可以换
###类的实例
seq1 <- DNAseq()
seq1

$`seq`
[1] "ATGCATGCATGCATGCATGC"

$length
[1] 20

attr(,"class")
[1] "list"   "DNAseq"

沿着上面创建的类,我们看看类的继承是怎么一回事

Primer <- function(seq = "ATGCATGCATGCATGCATGCGGCC"){ 
  pr <- strtrim(seq, 20) #strtrim是字符串修剪函数,即取seq的前20个字符
  me <- DNAseq(pr) 
  class(me) <- append(class(me), "Primer") 
  return(me)
}

Primer1 <- Primer()
Primer1

$`seq`
[1] "ATGCATGCATGCATGCATGC"

$length
[1] 20

attr(,"class")
[1] "list"   "DNAseq" "Primer" #结果继承关系从左到右依次

R语言S4类

有的程序员认为大多数S3类是list,所以不太正宗,所以升级成了更加安全的S4类,而S4类是由slots构成,我们先来简单看看创建S4类的方法

setClass(Class, representation, prototype, contains=character(), validity, access, where, version, sealed, package,  S3methods = FALSE, slots)

#Class:定义的类名
#slots:定义类的属性
#prototype:定义属性的默认值(这个有什么用,我还没有发掘)
#contains = character():定义父类和继承关系
#where:定义存储空间
#sealed:若是TRUE,则同类名不能被定义
#package:定义所属包

我们还是具体看个例子吧,

#定义个S4类,这个类有name和age两个属性
setClass("Person",slots = list(name="character",age="numeric"))
#实例化一个father
father <- new("Person",name="F",age=44) 
father

An object of class "Person"
Slot "name":
[1] "F"

Slot "age":
[1] 44

#查看father
class(father)
[1] "Person"
attr(,"package")
[1] ".GlobalEnv"

接下来我们讲一下S4类的继承

#创建一个S4类
setClass("Person",slots = list(name="character",age="numeric"))
#创建一个子类
setClass("Son",slots = list(father="Person",mother="Person"),contains = "Person")#contain表明类的继承关系,继承自Person
#实例化类
father <- new("Person",name="F",age=44)
father
An object of class "Person"
Slot "name":
[1] "F"

Slot "age":
[1] 44

mother <- new("Person",name="M",age=39)
mother
An object of class "Person"
Slot "name":
[1] "M"

Slot "age":
[1] 39

son <- new("Son",name="S",age=16,father=father,mother=mother)#实例化后要在后面注明继承来源father,mother
son
 son
An object of class "Son"
Slot "father":
An object of class "Person"
Slot "name":
[1] "F"

Slot "age":
[1] 44


Slot "mother":
An object of class "Person"
Slot "name":
[1] "M"

Slot "age":
[1] 39


Slot "name":
[1] "S"

Slot "age":
[1] 16

紧接着这个例子,我们来看看如何访问S4类的属性,在S4类中用@来访问类的属性


关于R的S3类S4类_第1张图片
访问
son@name
[1] "S"

son@age
[1] 16
#由于继承自Person,所以也可以访问Person的属性
son@father
An object of class "Person"
Slot "name":
[1] "F"

Slot "age":
[1] 44

son@mother
An object of class "Person"
Slot "name":
[1] "M"

Slot "age":
[1] 39

注意:代码参考自这两篇推送,如有侵权我立马删
1.https://mp.weixin.qq.com/s/LXAbDmLE4GnNlEq3qJoiiQ
2.https://mp.weixin.qq.com/s/eKVrJ3boaDbNurQwcDCi1g

你可能感兴趣的:(关于R的S3类S4类)