R开发(part11)--基于S4的面向对象编程
學(xué)習(xí)筆記,僅供參考,有錯(cuò)必糾
參考自:《R的極客理想》-- 張丹
文章目錄
- R開(kāi)發(fā)
- 基于S4的面向?qū)ο缶幊?/li>
- 創(chuàng)建S4對(duì)象
- 訪問(wèn)S4對(duì)象的屬性
- S4的泛型函數(shù)
- 查看S4對(duì)象的函數(shù)
R開(kāi)發(fā)
基于S4的面向?qū)ο缶幊?/h3>
S4對(duì)象系統(tǒng)是一種R語(yǔ)言面向?qū)ο髮?shí)現(xiàn)方式,S4對(duì)象有明確的類定義、參數(shù)定義、參數(shù)檢查、繼承關(guān)系、實(shí)例化、接口函數(shù)、實(shí)現(xiàn)函數(shù)等面向?qū)ο笙到y(tǒng)的特征。
創(chuàng)建S4對(duì)象
- setClass函數(shù)
S4對(duì)象系統(tǒng)有專門的類定義函數(shù)setClass和類的實(shí)例化函數(shù)new,我們先看看setClass的語(yǔ)法。
setClass語(yǔ)法:
setClass(Class, representation, prototype, contains=character(),validity, access, where, version, sealed, package,S3methods = FALSE, slots)setClass參數(shù)表:
| Class | 定義類名 |
| slots | 定義屬性和屬性類型 |
| prototype | 定義屬性的默認(rèn)值 |
| contains=character() | 定義父類,繼承關(guān)系 |
| validity | 定義屬性的類型檢查 |
| where | 定義存儲(chǔ)空間 |
| sealed | 如果設(shè)置TRUE,則同名類不能被再次定義 |
| package | 定義所屬的包 |
- 創(chuàng)建一個(gè)S4對(duì)象實(shí)例
通過(guò)setClass函數(shù)定義類的結(jié)構(gòu),再通過(guò)new函數(shù)來(lái)實(shí)例化類對(duì)象:
#定義一個(gè)S4對(duì)象 setClass("Person", slots = list(name = "character", age = "numeric"))#實(shí)例化一個(gè)Person對(duì)象 father <- new("Person", name = "F", age = 50) father #輸出start An object of class "Person" Slot "name": [1] "F"Slot "age": [1] 50 #輸出endclass(father) #輸出start [1] "Person" attr(,"package") [1] ".GlobalEnv" #輸出endotype(father) #"S4"- 創(chuàng)建一個(gè)有繼承關(guān)系的S4對(duì)象
如果需要?jiǎng)?chuàng)建有繼承關(guān)系的S4對(duì)象,可以通過(guò)setClass函數(shù)的contains屬性來(lái)設(shè)置父類:
#定義一個(gè)S4對(duì)象Person setClass("Person", slots = list(name = "character", age = "numeric"))#定義一個(gè)S4對(duì)象Son, 繼承Person setClass("Son", slots = list(father = "Person", mother = "Person"), contains = "Person")#實(shí)例化一個(gè)Person對(duì)象 father <- new("Person", name = "F", age = 50) mother <- new("Person", name = "M", age = 51)#實(shí)例化一個(gè)Son對(duì)象 son <- new("Son", name = "S", age = 22, father = father, mother = mother)son@name #"S" son@age #22 son@father #輸出start An object of class "Person" Slot "name": [1] "F"Slot "age": [1] 50 #輸出end#查看son對(duì)象的mother屬性 slot(son, "mother") #輸出start An object of class "Person" Slot "name": [1] "M"Slot "age": [1] 51 #輸出end# 檢查son類型 otype(son) #"S4" # 用isS4()檢查S4對(duì)象的類型 isS4(son) #TRUE #檢查son@mother屬性類型 otype(son@mother) #"S4"- S4對(duì)象的默認(rèn)值
通過(guò)setClass函數(shù)的prototype屬性給屬性字段中定義的參數(shù)設(shè)置默認(rèn)值:
#定義一個(gè)S4對(duì)象Bunny setClass("Bunny", slots = list(name = "character", age = "numeric"),prototype = list(age = 20))b <- new("Bunny", name = "Huang") b #輸出start An object of class "Bunny" Slot "name": [1] "Huang"Slot "age": [1] 20 #輸出end- S4對(duì)象的類型檢查
通過(guò)setValidity函數(shù)給屬性字段中定義的參數(shù)設(shè)置類型檢查:
#定義一個(gè)S4對(duì)象Person setClass("Person", slots = list(name = "character", age = "numeric"))setValidity("Person", function(object) {if (object@age <= 0 | object@age >= 100) {stop("年齡非法")} })p <- new("Person", name = "T", age = -1) #報(bào)錯(cuò)start Error in validityMethod(object) : 年齡非法 #報(bào)錯(cuò)end- 從一個(gè)已實(shí)例化的對(duì)象中創(chuàng)建新對(duì)象
S4對(duì)象還支持從一個(gè)已實(shí)例化的對(duì)象中創(chuàng)建新對(duì)象,創(chuàng)建時(shí)可以覆蓋對(duì)象的值:
# 創(chuàng)建一個(gè)對(duì)象實(shí)例n1 n1 <- new("Person", name="n1", age=19) # 從實(shí)例n1中創(chuàng)建實(shí)例n2,并修改name的屬性值 n2<-initialize(n1, name="n2")n1 #輸出start An object of class "Person" Slot "name": [1] "n1"Slot "age": [1] 19 #輸出endn2 #輸出start An object of class "Person" Slot "name": [1] "n2"Slot "age": [1] 19 #輸出end訪問(wèn)S4對(duì)象的屬性
在S3對(duì)象中,一般我使用$來(lái)訪問(wèn)一個(gè)對(duì)象的屬性。但在S4對(duì)象中,我們只能使用@來(lái)訪問(wèn)一個(gè)對(duì)象的屬性。
#定義一個(gè)S4對(duì)象 setClass("Person", slots = list(name = "character", age = "numeric"))#實(shí)例化一個(gè)Person對(duì)象 father <- new("Person", name = "F", age = 50) #訪問(wèn)S4對(duì)象的屬性 father@name #"F" slot(father, "name") #"F"S4的泛型函數(shù)
S4的泛型函數(shù)實(shí)現(xiàn)有別于S3的實(shí)現(xiàn),S4分離了方法的定義和實(shí)現(xiàn),如在其他語(yǔ)言中我們常說(shuō)的接口和實(shí)現(xiàn)分離。通過(guò)setGeneric來(lái)定義接口,通過(guò)setMethod來(lái)定義實(shí)現(xiàn)函數(shù)。
普通函數(shù)的定義和調(diào)用:
work <- function(x) cat(x, "is working") work("Huang") #Huang is workingS4的泛型函數(shù):
#定義一個(gè)Person類 setClass("Person", slots = list(name = "character", age = "numeric")) #定義泛型函數(shù)work,即接口 setGeneric("work", function(object) standardGeneric("work")) #定義work的實(shí)現(xiàn)函數(shù),并指定參數(shù)類型為Person類的對(duì)象 setMethod("work", signature(object = "Person"), function(object) cat(object@name, "is working"))p <- new("Person", name = "p1", age = 18) work(p) #p1 is working通過(guò)S4對(duì)象系統(tǒng),把原來(lái)的函數(shù)定義及調(diào)用過(guò)程從2步變成4步:
- 定義S4類;
- 定義接口函數(shù);
- 定義實(shí)現(xiàn)函數(shù);
- 把對(duì)象以參數(shù)傳入接口函數(shù),執(zhí)行實(shí)現(xiàn)函數(shù)。
查看S4對(duì)象的函數(shù)
當(dāng)我們使用S4對(duì)象進(jìn)行面向?qū)ο蠓庋b后,我們還需要能查看S4對(duì)象的定義和函數(shù)定義.
R>#檢查work的類型 R>ftype(work) [1] "s4" "generic" R>#直接查看work函數(shù) R>work standardGeneric for "work" defined from package ".GlobalEnv"function (object) standardGeneric("work") <environment: 0x0000000012708a68> Methods may be defined for arguments: object Use showMethods("work") for currently available ones. R>#查看work函數(shù)的現(xiàn)實(shí)定義 R>showMethods(work) Function: work (package .GlobalEnv) object="Person"R>#查看Person對(duì)象的work函數(shù)現(xiàn)實(shí) R>getMethod("work", "Person") Method Definition:function (object) cat(object@name, "is working")Signatures:object target "Person" defined "Person" R>#檢查Person對(duì)象有沒(méi)有work函數(shù) R>existsMethod("work", "Person") [1] TRUE總結(jié)
以上是生活随笔為你收集整理的R开发(part11)--基于S4的面向对象编程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ppt打开后不能编辑怎么办
- 下一篇: R开发(part12)--基于RC的面向