2020-11-02

对象定义方式setClass()

RGBcolor <- setClass(
  # 类名
  "RGBcolor",
  # 数据列表,用slots表示
  slots = c(r = "integer",
            g = "integer",
            b = "integer",
            label = "character"),
  #其他辅助元素,prototype参数用来设定初始值
  prototype = list(r = 0L,
                   g = 0L,
                   b = 0L,
                   label = "#00000"
  ),
  # 合法性检查
  validity = function(object){
    if(object@r<0 | object@g<0 | object@b<0){
      return("rediculous!")
    }
    if(object@r>255 | object@g>255 | object@b>255){
      return("rediculous!")
    }
    return(T)
  }
)
# 实例化一个对象
c1 <- RGBcolor(r=20L,g=20L,b=20L,label = "#8c567f")
showClass("RGBcolor")
showMethods("RGBcolor")

Class "RGBcolor" [in ".GlobalEnv"]
Slots:                                           
Name:          r         g         b     label
Class:   integer   integer   integer character

Function "RGBcolor":
 <not an S4 generic function>

通过绑定构造函数的方式进行初值的处理,绑定方法使用setMethod()函数来进行,实际上绑定的是泛型函数

setMethod("initialize",signature(.Object = "RGBcolor"),
          function(.Object, r = 0L, g = 0L,b = 0L){
            .Object@r = as.integer(r)
            .Object@g = as.integer(g)
            .Object@b = as.integer(b)
            hx <- as.hexmode(c(r,g,b))
            .Object@label=paste(c("#",format(hx,width = 2)),collapse = "")
           if(.Object@r>255 | .Object@g>255 | .Object@b>255){
              cat("warning!RGB can't >255!")
             #想要停止构造对象
             # stop("rediculous") 
            }
            return(.Object)
          }                    
         )

c1 <- RGBcolor(r = 2000,g = 60 ,b = 135)
warning!RGB can't >255!
#=======================================
view(initialize)
target = new("signature", .Data = "ANY", names = ".Object", 
      package = "methods"), defined = new("signature", 
      .Data = "ANY", names = ".Object", package = "methods"), 
    generic = "initialize") 

创建新的泛型函数(类似于抽象方法)

setGeneric("modColor" , function(.Object,name,value) standardGeneric("modColor"))
setMethod("modColor",signature(.Object = "RGBcolor",
                               name = "character",
                               value = "numeric"),
          function(.Object,name,value){
            if(!name %in% c("r","g","b")){
              stop("rediculous!")
            }
            slot(.Object,name) <- as.integer(value)
            hx <- as.hexmode(c(.Object@r,.Object@g,.Object@b))
            .Object@label=paste(c("#",format(hx,width = 2)),collapse = "") 
           return(.Object)   
          }
) 
# 方法的重载
setMethod("modColor",signature(.Object = "RGBcolor"
                              ),
          function(.Object){
            return(.Object)
          }
          
          
          )           
#================================
c2<- RGBcolor(23,62,95)
modColor(c2,"g",34)
c2@g
c2@label 
[1] "modColor"
[1] 62
[1] "#173e5f"
c2<- modColor(c2,"g",34) 
c2@g
c2@label
[1] 34
[1] "#17225f"

理解泛型函数底层原理

hx <- as.hexmode(c(100,100,100))
paste(c("#",hx),collapse = "")
print(c("#",hx))
print(hx)
[1] "#100100100"
[1] "64" "64" "64"
[1] "#"   "100" "100" "100"
#==================================
view(print)
function (x, ...) 
UseMethod("print")
# R使用泛型函数来处理标记为不同class的数据
# 实际上我们对于某种class的数据,是调用的函数名.class名的对应函数
#==================================
class(hx)
[1] "hexmode"
#print(hx)实际上是print.hexmode(hx)
#==================================
view(print.hexmode)
function (x, ...) 
{
  print(format(x), ...)
  invisible(x)
}
#==================================
view(foramt)
function (x, ...) 
UseMethod("format")
#==================================
view(format.hexmode)
function (x, width = NULL, upper.case = FALSE, ...) 
{
  isna <- is.na(x)
  y <- as.integer(x[!isna])
  fmt0 <- if (upper.case) 
    "X"
  else "x"
  fmt <- if (!is.null(width)) 
    paste0("%0", width, fmt0)
  else paste0("%", fmt0)
  ans <- rep.int(NA_character_, length(x))
  ans0 <- sprintf(fmt, y)
  if (is.null(width) && length(y) > 1L) {
    nc <- max(nchar(ans0))
    ans0 <- sprintf(paste0("%0", nc, fmt0), y)
  }
  ans[!isna] <- ans0
  dim(ans) <- dim(x)
  dimnames(ans) <- dimnames(x)
  names(ans) <- names(x)
  ans
}
#===============================
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352