R:setGeneric 具有两个不同的 S4 类(B 继承 A),具有相同的方法名称和签名

问题描述 投票:0回答:1

有A、B两个班。
B 延伸 A。
对于 A 有一种方法

doStuffs
,对于 B 有一种方法。
他们具有相同的名称和签名,只是他们在不同的对象上工作,因此他们做不同的事情。

methods::setClass(
  Class = "A",
  slots = list(
    a = "character",
    b = "character"
  )
)

setGeneric("doStuffs", signature ="obj",
    function(obj,...) standardGeneric("doStuffs")
)
setClass(
  Class = "B",
  contains = "A",
  slots = list(
    c = "character"
  )
)

setGeneric("doStuffs", signature ="obj",
    function(obj,...) standardGeneric("doStuffs")
)

当我打电话时:

obj <- new A(a="a",b="b")
showMethods("doStuffs")
doStuffs(obj)

功能:doStuffs(包blahblah)
对象=“B”

无法找到函数的继承方法 'doStuffs' 代表签名 'obj = "A"'

如果我对两个泛型使用以下代码,它就可以工作。
不知道为什么。
showMethods 找到两个泛型。

if (!isGeneric("doStuffs")) {
    if (is.function("doStuffs")) {
        fun <- doStuffs
    } else {
        fun <- function(obj, ...) standardGeneric("doStuffs")
    }

功能:doStuffs(包blahblah)
对象=“A”
对象=“B”

为什么这有效?如何编写这个“好方法”?

r bioconductor r-s4
1个回答
0
投票

正如评论中所讨论的,您滥用了

setGeneric
(而不是使用
setMethod
)。

使用您定义的类定义,首先定义泛型:

setGeneric(
  "doStuffs",
  function(obj,...) standardGeneric("doStuffs")
)
"doStuffs"

现在定义几个对象

obj1 <- new ("A", a = "A", b = "B")
obj2 <- new ("B", a = "C", b = "D")

接下来,为超类定义一个方法。

setMethod(
  "doStuffs",
  signature = signature(obj = "A"),
  def = function(obj) {
    "Hello from A"
  }
)

看看会发生什么:

doStuffs(obj1)
[1] "Hello from A"
doStuffs(obj2)
[1] "Hello from A"

这是正确的:类

doStuffs
没有
B
方法,因此类
B
的对象使用超类的方法。

现在为类

B
定义一个方法。

setMethod(
  "doStuffs",
  signature = signature(obj = "B"),
  def = function(obj) {
    "Hello from B"
  }
)

并重复。

doStuffs(obj1)
[1] "Hello from A"
doStuffs(obj2)
[1] "Hello from B"

一切都好。

© www.soinside.com 2019 - 2024. All rights reserved.