R语言: S3类&S4类
2023-03-14 本文已影响0人
LET149
S3类和S4类都是R语言中的类,具有属性和方法,可以继承和实例化
1. S3类
S3类的本质是一个列表,而列表中的每个元素都是一种数据
1.1 创建一个列表
列表本身是一个类,也就是列表类
> aa <- list(bb=c(2,4,5),cc=c("dd","sdfsd"),dd=c(2,3,7)) #创建一个名为aa的列表
> class(aa) #查看aa这个列表当前所属的类
[1] "list" #当前仅为列表类
> aa #查看aa这个列表的属性,即查看其中的每一个元素
$bb #属性一,即元素一
[1] 2 4 5
$cc
[1] "dd" "sdfsd"
$dd
[1] 2 3 7
![](https://img.haomeiwen.com/i23414774/9c2de72936429d8b.png)
1.2 创建一个新类
- 此新类的创建方法给已经存在的列表添加一个新的类名,其本质是此新类对列表这个类的继承
- 创建的这个新类到目前为止,只有属性,没有方法
class(aa) <- append(class(aa),"kkk") #在aa的类名中添加kkk类名,此时的aa即是list类,也是kkk类,也就是kkk类继承了list类
> class(aa) <- append(class(aa),"kkk")
> aa #查看aa的属性
$bb #打印第一个属性,也是第一个元素
[1] 2 4 5
$cc
[1] "dd" "sdfsd"
$dd
[1] 2 3 7
attr(,"class") #新出现的属性,内容为aa所属的类
[1] "list" "kkk" #aa现在属于list类和kkk类,类的继承关系从左到右
![](https://img.haomeiwen.com/i23414774/17d852bb962f0415.png)
1.3 使用定义函数的方式创建一个新类
SEQ <- function(seq = "ATGCATGCATGCATGCATGC"){ #用函数来定义类,seq是自变量并给出初始值
me <- list( seq = seq, length = nchar(seq) ) # 定义一个列表类
class(me) <- append(class(me), "DNAseq") #定义一个新类名来继承上面定义的列表类
return(me) #函数的返回值是列表类的全部属性及其值
} #函数名SEQ并不是类名,调用类时,直接调用函数即可
seq1 <- SEQ() #通过函数来创建一个实例
> seq1 <- RNAseq()
> seq1 #查看实例属性
$seq
[1] "ATGCATGCATGCATGCATGC"
$length
[1] 20
attr(,"class")
[1] "list" "DNAseq"
![](https://img.haomeiwen.com/i23414774/4708be35de1ce8bc.png)
1.4 S3类中属性的调用
实例名$属性名
![](https://img.haomeiwen.com/i23414774/ddbf7cca6ef0b753.png)
2. S4类
S4类由slots构成,相比S3类更加安全
2.1 创建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:定义所属包
2.2 一个具体的创建例子
setClass("Person",slots = list(name="character",age="numeric")) #创建类
father <- new("Person",name="F",age=44) #实例化
father #查看实例属性(slots中的元素)
An object of class "Person"
Slot "name":
[1] "F"
Slot "age":
[1] 44
class(father) #查看实例的类别
[1] "Person"
attr(,"package")
[1] ".GlobalEnv"
2.3 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
![](https://img.haomeiwen.com/i23414774/6168cb8d912a8401.png)
2.4 S4类中属性的调用
实例名@属性名
![](https://img.haomeiwen.com/i23414774/698d7d74163ec91b.png)
3. Seurat中的数据结构
- Seurat中的数据为Seurat类
- 其中既包含S4类又包含S3类
- 在调用时,分清是S4类还是S3类,然后做相应的属性调用即可
参考: