我有一个基类(我们称之为"A"),其表示形式与许多其他类相同.
因此,我定义其他类,如"B",以包含此类.
我想设置这些其他类(B)的原型,以包含从A继承的插槽的默认值.我认为这很自然:
setClass("A", representation(a="character"))
setClass("B", contains="A", prototype(a = "hello"))
Run Code Online (Sandbox Code Playgroud)
但它会产生错误:
Error in representation[!slots] : object of type 'S4' is not subsettable
Run Code Online (Sandbox Code Playgroud)
不知道为什么会这样.如果我省略原型,我可以做:
setClass("B", contains="A")
Run Code Online (Sandbox Code Playgroud)
然后破解我自己的生成器功能:
new_B <- function(...){
obj <- new("B", ...)
obj@a = "hello"
obj
}
Run Code Online (Sandbox Code Playgroud)
然后根据原型创建我的对象new_B(),但与使用通用生成器new("B")和我的原型相比,这非常粗糙和丑陋......
补充我的评论而不是提供问题的新答案,这里是一个解决方案,我们仍然按位置匹配参数(因为我们为B类指定了额外的表示):
.A <- setClass("A", representation(a="character"))
.B <- setClass("B", representation(b="numeric"),
prototype(a="hello"),
contains="A")
Run Code Online (Sandbox Code Playgroud)
.A()和.B()替换调用new("A")和new("B").在某种程度上,这是语法糖,但可以使对象构造更透明
## construct an object using B's prototype, like new("B", b=1:3)
> .B(b=1:3)
An object of class "B"
Slot "b":
[1] 1 2 3
Slot "a":
[1] "hello"
## construct an object using A's prototype, like new("B", new("A"), b=1:3)
> .B(.A(), b=1:3)
An object of class "B"
Slot "b":
[1] 1 2 3
Slot "a":
character(0)
Run Code Online (Sandbox Code Playgroud)
(第二个示例使用了无名参数new或B用于初始化继承类的事实).
用户不必非常友好地使用.A或.B直接使用,例如,因为签名是公正的...,因此将被记录为"参见A类槽的定义".这破坏了接口和实现的分离,这是OOP的优势.此外,最后一个代码块(.B(.A(a=a), b=b)或.B(a=a, b=b))中的一个或另一个行为可能不是意图.因此,而不是提供一个功能被暴露给用户,也许做了一些初步的数据按摩
A <- function(a=character(), ...) {
## nothing special, just a public constructor
.A(a=a, ...)
}
B <- function(b, a="hello", ...) {
a <- tolower(a) ## no SHOUTing!
.B(A(a=a), b=b) ## A's public interface; no need for B to know A's details
}
Run Code Online (Sandbox Code Playgroud)
函数A和B定义接口,为用户提供有关可接受参数的提示,而无需将构造函数绑定到类定义,并执行初步数据按摩.后者可以使initialize方法变得不必要,这是一件好事,因为它们有一个复杂的契约(它们应该初始化并且是复制构造函数,正如我们在上面看到的那样,未命名的参数应该初始化基类),这是大多数人得到的错误.
这些只是我的意见.
您只需命名参数:
setClass("A", representation(a="character"))
setClass("B", contains="A", prototype=prototype(a="hello"))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
721 次 |
| 最近记录: |