R语言类
R语言的类有S3类和S4类,S3类用的比较广,创建简单粗糙但是灵活,而S4类比较精细,具有跟C++一样严格的结构。这里我们主要讲S3类。
S3类的结构
S3类内部是一个list,append某个list类名称,就能成为该类。list里面的内容就是我们所说的属性.
首先创建一个list
me <- list(seq = "ATGC", length = nchar("ATGC"))
me
$seq
[1] "ATGC"
$length
[1] 4
现在me这个list只属于list类
me
$seq
[1] "ATGC"
$length
[1] 4
attr(,"class")
[1] "list" "DNAseq"
然后我们append 一个类名"DNAseq",就这样我们创建了一个DNAseq类,类的属性有seq和length,值为ATGC和4
class(me) <- append(class(me), "DNAseq")
class(me)
[1] "list" "DNAseq"
我们可以通过普通的list的方法来获得类的属性,比如
me$seq
[1] "ATGC"
me$length
[1] 4
S3类的创建
简单直接的构建方法
依据刚才的类的结构,我们用函数进行类的构建,函数的输入是要传入进行类的初始化的值,而函数的返回就是新生成的类。这样我们就可以根据不同的初始化值进行类的实例化。
首先构造一个类
# Straight forward approach
DNAseq <- function(seq = "ATGCATGCATGCATGCATGC"){
me <- list(
seq = seq,
length = nchar(seq)
)
# Set the name for the class
class(me) <- append(class(me), "DNAseq")
return(me)
}
类的实例
seq1 <- DNAseq()
seq1
$seq
[1] "ATGCATGCATGCATGCATGC"
$length
[1] 20
attr(,"class")
[1] "list" "DNAseq"
局部环境构建类的方法
当然本质还是list,但是巧妙的利用了函数运行时的局部环境。函数运行时,内部的环境是和外界隔离的,在函数内创建的变量不会影响函数外。而这种方法巧妙的取出了这个内部环境的指针,并且将它放到了list里面。最后append类名。在环境里面存放了list的指针,而在list里面又存放了环境的指针。之所以内部环境没有消失,我猜想是因为返回的类里面具有环境的指针的引用,所以内存没有释放,是一个智能指针,当然,我没有对这深究。这次属性并不是直接存放在list里面,而是存放在函数里面的环境中。而list里面放着:方法和当前环境的指针。assign是对环境中某个变量赋值,可以用get函数中获得环境中变量的值。
# Local enviroment approach
DNASeq <- function(seq = "ATGCATGCATGCATGCATGC"){
## Get the enviroment for this
thisEnv <- environment()
seq <- seq
length <- nchar(seq)
## Create the list used to represent the
## object for this class
me <- list(
## Define the enviroment where this list is defined so
## that I can refer to it
thisEnv = thisEnv,
## Method to refer to the current enviroment
getEnv = function(){
return(get("thisEnv", thisEnv))
}
)
## Define the value of list within the
## current enviroment
assign("this", me, envir = thisEnv)
##Set the name for the class
class(me) <- append(class(me), "DNASeq")
return(me)
}
实例化
seq2 <- DNASeq()
seq2
$thisEnv
<environment: 0x8e86a20>
$getEnv
function ()
{
return(get("thisEnv", thisEnv))
}
<environment: 0x8e86a20>
$getseq
function ()
{
return(get("seq", thisEnv))
}
<environment: 0x8e86a20>
$reverseComplement
function ()
{
print("Calling the reverseComplement function of DNASeq class")
to_base <- c("A", "T", "G", "C")
names(to_base) <- c("T", "A", "C", "G")
trans_seq_vect <- to_base[unlist(strsplit(get("seq", thisEnv),
split = ""))]
trans_rev_vect <- trans_seq_vect[length(trans_seq_vect):1]
newseq <- paste0(trans_rev_vect, collapse = "")
return(DNASeq(newseq))
}
<environment: 0x8e86a20>
attr(,"class")
[1] "list" "DNASeq"
获得里面的seq属性的值,这里使用get获得环境中的变量的值
get("seq", seq2$getEnv())
[1] "ATGCATGCATGCATGCATGC"
当然,如果使用这种方法生成的类,我们获得属性通常不再函数外用get,因为这样并不像面向对象的用法,我们会在给