为 R 类 和 sub类 使用多个构造函数
Using multiple constructors for R classes and subclasses
我想在我的 R S4 中使用多个构造函数 class。
我有一个具有三个插槽的对象。为了制作那个对象,有时我只想直接给出三个插槽的值。但有时我想提供一个矩阵,我有一个函数可以接受一个矩阵和return这三个槽应该是什么。
起初,我似乎可以编写一个函数作为构造函数。所以我可以写 objectFromMatrix(matrix) --> object with three slots
。问题是我也有继承自主 class 的子 classes,并且我也希望能够与它们一起使用该构造函数。
所以我可以为每个子classes 编写函数作为额外的构造函数,但这会有点乏味而且不像超级 OO。
为了让我的问题更具体一些,我将尝试在下面写一个最小的例子。我会把它写在 Java 中,但我有点生疏,所以如果它没有意义,请告诉我。
所需的结构,在 Java 中:
// An abode is a place where you live and it has a size
class Abode {
int size = 1;
// Main constructor that just assigns args to fields
Abode(int size) {
this.size = size;
}
// Alternative constructor that takes in a different datatype
// and computes args to assign to fields
Abode(string description) {
if(description eq "Large") {
this.size = 5;
}
if(description eq "Small") {
this.size = 1;
}
}
// To keep it simple, a house is just an abode with a name
class House extends Abode {
String name;
House(int size, String name) {
super(size);
this.name = name;
}
House(string size, String name) {
super(size);
this.name = name;
}
}
这个实现工作得很好,因为我可以调用 Abode("big")
或 House("big", "Casa de me")
,并且这两个都被传递给我在 Abode
class 中构建的额外构造函数。
跟上房子的类比,这是我在 R 中能做的最好的事情:
# An abode is a place you live and it has a size
setClass("Abode",
slots =
list(size = "numeric")
)
# Alternative constructor that takes in a different datatype
# and computes args to assign to fields
abode_constructor_2 <- function(sizeString) {
if (sizeString == "big") {return new("Abode", size = 5)}
if (sizeString == "small") {return new("Abode", size = 1)}
}
# A house is an abode with a name
setClass("House",
slots =
list(name = "string"),
contains = "Abode"
)
# I already defined this constructor but I have to do it again
house_constructor_2 <- function(sizeString, name) {
if (sizeString == "big") {return new("House", size = 5, name = name)}
if (sizeString == "small") {return new("House", size = 1, name = name)}
}
如果有帮助,这里是出现此问题的真实上下文的最小示例。我为 Sensor
class、sensor_constructor_2
定义了一个额外的构造函数作为函数。但是,当我有一个从 Sensor
继承的 class 时,我必须重新构造该构造函数。
# A sensor has three parameters
setClass("Sensor",
slots =
list(Rmin = "numeric", Rmax = "numeric", delta = "numeric")
)
# I also like to make sensors from a matrix
sensor_constructor_2 <- function(matrix) {
params <- matrix_to_params(matrix)
return (new("Sensor", Rmin = params[1], Rmax = params[2], delta = params[3]))
}
# A redoxSensor is just a sensor with an extra field
setClass("redoxSensor",
slots =
list(e0 = "numeric"),
contains = "Sensor"
)
# Goal: make this extra constructor unnecessary by making sensor_constructor_2 a property of the sensor class
extraConstructor_redox <- function(matrix, e0) {
params <- matrix_to_params(matrix)
return (new("redoxSensor", Rmin = params[1], Rmax = params[2], delta = params[3]), e0 = e0)
}
您没有理由不能通过使用默认参数和一些额外的逻辑来使用一个 S4 构造函数,按照
setClass("Abode",
slots = list(size = "numeric")
) -> Abode
setClass("House",
slots = list(name = "character"),
contains = "Abode"
) -> House
createDwelling <- function(size=0,name,sizeString){
if(!missing(sizeString)){
if(sizeString == "Large") size <- 5
else if(sizeString == "Small") size <- 1
else stop("invalid sizeString")
}
if(missing(name)) return(Abode(size=size))
else return(House(size=size,name=name))
}
用法示例:
> createDwelling(size=3)
An object of class "Abode"
Slot "size":
[1] 3
> createDwelling(sizeString="Small")
An object of class "Abode"
Slot "size":
[1] 1
> createDwelling(sizeString="Small",name="my house")
An object of class "House"
Slot "name":
[1] "my house"
Slot "size":
[1] 1
我想在我的 R S4 中使用多个构造函数 class。
我有一个具有三个插槽的对象。为了制作那个对象,有时我只想直接给出三个插槽的值。但有时我想提供一个矩阵,我有一个函数可以接受一个矩阵和return这三个槽应该是什么。
起初,我似乎可以编写一个函数作为构造函数。所以我可以写 objectFromMatrix(matrix) --> object with three slots
。问题是我也有继承自主 class 的子 classes,并且我也希望能够与它们一起使用该构造函数。
所以我可以为每个子classes 编写函数作为额外的构造函数,但这会有点乏味而且不像超级 OO。
为了让我的问题更具体一些,我将尝试在下面写一个最小的例子。我会把它写在 Java 中,但我有点生疏,所以如果它没有意义,请告诉我。
所需的结构,在 Java 中:
// An abode is a place where you live and it has a size
class Abode {
int size = 1;
// Main constructor that just assigns args to fields
Abode(int size) {
this.size = size;
}
// Alternative constructor that takes in a different datatype
// and computes args to assign to fields
Abode(string description) {
if(description eq "Large") {
this.size = 5;
}
if(description eq "Small") {
this.size = 1;
}
}
// To keep it simple, a house is just an abode with a name
class House extends Abode {
String name;
House(int size, String name) {
super(size);
this.name = name;
}
House(string size, String name) {
super(size);
this.name = name;
}
}
这个实现工作得很好,因为我可以调用 Abode("big")
或 House("big", "Casa de me")
,并且这两个都被传递给我在 Abode
class 中构建的额外构造函数。
跟上房子的类比,这是我在 R 中能做的最好的事情:
# An abode is a place you live and it has a size
setClass("Abode",
slots =
list(size = "numeric")
)
# Alternative constructor that takes in a different datatype
# and computes args to assign to fields
abode_constructor_2 <- function(sizeString) {
if (sizeString == "big") {return new("Abode", size = 5)}
if (sizeString == "small") {return new("Abode", size = 1)}
}
# A house is an abode with a name
setClass("House",
slots =
list(name = "string"),
contains = "Abode"
)
# I already defined this constructor but I have to do it again
house_constructor_2 <- function(sizeString, name) {
if (sizeString == "big") {return new("House", size = 5, name = name)}
if (sizeString == "small") {return new("House", size = 1, name = name)}
}
如果有帮助,这里是出现此问题的真实上下文的最小示例。我为 Sensor
class、sensor_constructor_2
定义了一个额外的构造函数作为函数。但是,当我有一个从 Sensor
继承的 class 时,我必须重新构造该构造函数。
# A sensor has three parameters
setClass("Sensor",
slots =
list(Rmin = "numeric", Rmax = "numeric", delta = "numeric")
)
# I also like to make sensors from a matrix
sensor_constructor_2 <- function(matrix) {
params <- matrix_to_params(matrix)
return (new("Sensor", Rmin = params[1], Rmax = params[2], delta = params[3]))
}
# A redoxSensor is just a sensor with an extra field
setClass("redoxSensor",
slots =
list(e0 = "numeric"),
contains = "Sensor"
)
# Goal: make this extra constructor unnecessary by making sensor_constructor_2 a property of the sensor class
extraConstructor_redox <- function(matrix, e0) {
params <- matrix_to_params(matrix)
return (new("redoxSensor", Rmin = params[1], Rmax = params[2], delta = params[3]), e0 = e0)
}
您没有理由不能通过使用默认参数和一些额外的逻辑来使用一个 S4 构造函数,按照
setClass("Abode",
slots = list(size = "numeric")
) -> Abode
setClass("House",
slots = list(name = "character"),
contains = "Abode"
) -> House
createDwelling <- function(size=0,name,sizeString){
if(!missing(sizeString)){
if(sizeString == "Large") size <- 5
else if(sizeString == "Small") size <- 1
else stop("invalid sizeString")
}
if(missing(name)) return(Abode(size=size))
else return(House(size=size,name=name))
}
用法示例:
> createDwelling(size=3)
An object of class "Abode"
Slot "size":
[1] 3
> createDwelling(sizeString="Small")
An object of class "Abode"
Slot "size":
[1] 1
> createDwelling(sizeString="Small",name="my house")
An object of class "House"
Slot "name":
[1] "my house"
Slot "size":
[1] 1