R开发(part11)--基于S4的面向对象编程
學習筆記,僅供參考,有錯必糾
參考自:《R的極客理想》-- 張丹
文章目錄
- R開發
- 基于S4的面向對象編程
- 創建S4對象
- 訪問S4對象的屬性
- S4的泛型函數
- 查看S4對象的函數
R開發
基于S4的面向對象編程
S4對象系統是一種R語言面向對象實現方式,S4對象有明確的類定義、參數定義、參數檢查、繼承關系、實例化、接口函數、實現函數等面向對象系統的特征。
創建S4對象
- setClass函數
S4對象系統有專門的類定義函數setClass和類的實例化函數new,我們先看看setClass的語法。
setClass語法:
setClass(Class, representation, prototype, contains=character(),validity, access, where, version, sealed, package,S3methods = FALSE, slots)setClass參數表:
| Class | 定義類名 |
| slots | 定義屬性和屬性類型 |
| prototype | 定義屬性的默認值 |
| contains=character() | 定義父類,繼承關系 |
| validity | 定義屬性的類型檢查 |
| where | 定義存儲空間 |
| sealed | 如果設置TRUE,則同名類不能被再次定義 |
| package | 定義所屬的包 |
- 創建一個S4對象實例
通過setClass函數定義類的結構,再通過new函數來實例化類對象:
#定義一個S4對象 setClass("Person", slots = list(name = "character", age = "numeric"))#實例化一個Person對象 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"- 創建一個有繼承關系的S4對象
如果需要創建有繼承關系的S4對象,可以通過setClass函數的contains屬性來設置父類:
#定義一個S4對象Person setClass("Person", slots = list(name = "character", age = "numeric"))#定義一個S4對象Son, 繼承Person setClass("Son", slots = list(father = "Person", mother = "Person"), contains = "Person")#實例化一個Person對象 father <- new("Person", name = "F", age = 50) mother <- new("Person", name = "M", age = 51)#實例化一個Son對象 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對象的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對象的類型 isS4(son) #TRUE #檢查son@mother屬性類型 otype(son@mother) #"S4"- S4對象的默認值
通過setClass函數的prototype屬性給屬性字段中定義的參數設置默認值:
#定義一個S4對象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對象的類型檢查
通過setValidity函數給屬性字段中定義的參數設置類型檢查:
#定義一個S4對象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) #報錯start Error in validityMethod(object) : 年齡非法 #報錯end- 從一個已實例化的對象中創建新對象
S4對象還支持從一個已實例化的對象中創建新對象,創建時可以覆蓋對象的值:
# 創建一個對象實例n1 n1 <- new("Person", name="n1", age=19) # 從實例n1中創建實例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訪問S4對象的屬性
在S3對象中,一般我使用$來訪問一個對象的屬性。但在S4對象中,我們只能使用@來訪問一個對象的屬性。
#定義一個S4對象 setClass("Person", slots = list(name = "character", age = "numeric"))#實例化一個Person對象 father <- new("Person", name = "F", age = 50) #訪問S4對象的屬性 father@name #"F" slot(father, "name") #"F"S4的泛型函數
S4的泛型函數實現有別于S3的實現,S4分離了方法的定義和實現,如在其他語言中我們常說的接口和實現分離。通過setGeneric來定義接口,通過setMethod來定義實現函數。
普通函數的定義和調用:
work <- function(x) cat(x, "is working") work("Huang") #Huang is workingS4的泛型函數:
#定義一個Person類 setClass("Person", slots = list(name = "character", age = "numeric")) #定義泛型函數work,即接口 setGeneric("work", function(object) standardGeneric("work")) #定義work的實現函數,并指定參數類型為Person類的對象 setMethod("work", signature(object = "Person"), function(object) cat(object@name, "is working"))p <- new("Person", name = "p1", age = 18) work(p) #p1 is working通過S4對象系統,把原來的函數定義及調用過程從2步變成4步:
- 定義S4類;
- 定義接口函數;
- 定義實現函數;
- 把對象以參數傳入接口函數,執行實現函數。
查看S4對象的函數
當我們使用S4對象進行面向對象封裝后,我們還需要能查看S4對象的定義和函數定義.
R>#檢查work的類型 R>ftype(work) [1] "s4" "generic" R>#直接查看work函數 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函數的現實定義 R>showMethods(work) Function: work (package .GlobalEnv) object="Person"R>#查看Person對象的work函數現實 R>getMethod("work", "Person") Method Definition:function (object) cat(object@name, "is working")Signatures:object target "Person" defined "Person" R>#檢查Person對象有沒有work函數 R>existsMethod("work", "Person") [1] TRUE總結
以上是生活随笔為你收集整理的R开发(part11)--基于S4的面向对象编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ppt打开后不能编辑怎么办
- 下一篇: R开发(part12)--基于RC的面向