类一个方法,某个类调用这个方法之后就可以获得某个属性的值,比如可以在list中再写一个函数,getseq,就等于get("seq", thisEnv),这样就可以面向对象的使用seq2$getseq()来获得seq属性。当我们列表中添加方法时,注意应该用遵循列表的格式,用",”分开不同的方法或者不同的值。
创建方法
类中除了含有属性外,肯定还得含有方法。上面我们讲到用局部环境变量创建S3类时可以在list里面存放方法。当然还有一种比较普遍的,在两种方式创建的S3类中都能使用的创建方法的途径。使用某方法.某类来创建某类的方法。比如print.gg就是对gg类的print的方法。但是在创建这种方法之前我们首先得用这个方法的名字创建一个函数,这样运行函数时首先进入这个函数,然后在函数里面使用useMethod函数,在环境中寻找该类的该方法。虽然下面的代码比较复杂,但是重点时看UseMethod。
# Creating methods
reverseComplement <- function(object){
UseMethod("reverseComplement", object)
}
reverseComplement.default <- function(object){
print("The class of this object can not be found")
}
# Straight forward approach
#
# For S3 classes created by Straight forward approach
reverseComplement.DNAseq <- function(object){
print("Calling the reverseComplement function of DNAseq class")
## Compelement according to the vector below
to_base <- c("A", "T", "G", "C")
names(to_base) <- c("T", "A", "C", "G")
## Transform long charactor to vector and complement
trans_seq_vect <- to_base[unlist(strsplit(object$seq, split = ""))]
## Reverse
trans_rev_vect <- trans_seq_vect[length(trans_seq_vect):1]
## Collape to long character
newseq <- paste0(trans_rev_vect, collapse = "")
# Return a new DNAseq class
return(DNAseq(newseq))
}
# For S3 classed created by local enviroment approach
reverseComplement.DNASeq <- function(object){
print("Calling the reverseComplement function of DNASeq class")
## Compelement according to the vector below
to_base <- c("A", "T", "G", "C")
names(to_base) <- c("T", "A", "C", "G")
## Transform long charactor to vector and complement
trans_seq_vect <- to_base[unlist(strsplit(get("seq", seq2$getEnv()), split = ""))]
## Reverse
trans_rev_vect <- trans_seq_vect[length(trans_seq_vect):1]
## Collape to long character
newseq <- paste0(trans_rev_vect, collapse = "")
# Return a new DNASeq class
return(DNASeq(newseq))
}
上面还有一个default函数,表示默认的方法,如果该类找不到该类匹配的方法,就会使用默认方法。
类继承
S3类可以使用继承,在原来类的基础上再append一个新的类名即为新的类,用NextMethod可以调用下一层类的方法。
创建一个primer类继承DNAseq类
#inheritance
Primer <- function(seq = "ATGCATGCATGCATGCATGCGGCC"){
pr <- 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"
调用方法的时候会按照从左到右的顺序,再这个例子中,默认先调用DNAseq的方法,如果想要调用Primer类的方法,首先写一个Primer的reverseComplement方法
# Creating methods
reverseComplement.Primer <- function(object){
print("Running reverseComplement of Primer class")
}
然后在DNAseq类中调用下一类的方法,使用NextMethod
reverseComplement.DNAseq <- function(object){
print("Calling the reverseComplement function of DNAseq class")
NextMethod("reverseComplement", object)
## Compelement according to the vector below
to_base <- c("A", "T", "G&q