【发布时间】:2014-09-01 07:25:51
【问题描述】:
在 R 中,继承可以通过以下方式扩展基于列表的类来实现:
假设lmo 是从线性模型拟合获得的lm 类的对象。该类可以简单地通过以下方式扩展:
x <- rnorm(1000)
y <- rexp(1000)
lmo <- lm(x~y)
lmo$addition <- "some more information"
class(lmo) <- c("lmext","lm")
我仍然可以使用所有适用于lm 的方法,例如summary.lm,但也可以定义自定义方法。显然,在很多情况下,您只想添加最少的内容,并且仍然希望能够使用父类中的所有方法。
为不基于列表的类添加其他属性和实现方法继承的最佳方法是什么,例如时间序列? 这是我能想象的:
ts1 <- ts(rnorm(100),start = c(1990,1),frequency = 4)
attr(ts1,"additional") <- "some more information"
class(ts1) <- c("tsext","ts")
print.tsext <-
# some method that uses the original print method for ts, plus extracts
# the additional information
这是实现 + 等运算符的好方法吗?仍然可以在不为新类重新定义所有内容的情况下工作?有更好的吗?当例如将两个系列相互添加而不重新定义所有基本运算符时,有没有办法保留附加的类/属性?
【问题讨论】:
-
从列表继承没有什么特别之处。 S3 类的继承按照您的描述工作。由于这种继承,父类的方法将可用。但是,正如您所指出的,父类方法可能无法保持您的新属性完好无损。在这种情况下,您可能必须重新定义所有影响您的属性的方法。至少,我不知道有什么不同的方法。
-
@Andrie 感谢您的洞察力。尽管列表确实没有什么特别之处,但不同之处在于保留列表元素比保留属性更容易——至少从我尝试过的情况来看是这样。特别是重新定义所有运算符对我来说似乎很麻烦。像您这样更有经验的用户没有看到不同的方式,这并不完全令人鼓舞......
-
在添加两个对象的情况下,“保留额外的类属性”是什么意思? R在添加时无法知道您想对附加属性做什么。您将不得不覆盖运算符。但是您可以通过“Ops”缩短代码,例如要替换所有 2 元运算符,您可以使用
"Ops.MyNewClass" <- function(e1, e2) { atts <- MakeAttributes(e1, e2); res <- NextMethod(e1, e2); res <- AddAttributes(res, atts); res }其中 NextMethod 为父类调用通常的加法/减法/等。 -
@PatrickRoocks 非常酷。我只是希望得到这样的提示。我没有听说过
Ops可以访问所有二元运算符。你从哪里学来的?也许这只是我没有阅读的具体帮助文档。 -
其实我不知道我是在哪里第一次看到这个的。前段时间我问了question about operator overloading for functions,在那里我得到了一些提示。可能我在谷歌搜索时看到了一些带有“Ops”的示例代码......
?S3groupGeneric和?S4groupGeneric告诉我们一些有关机制的信息,但那里的示例并没有真正的帮助:-/
标签: r oop inheritance