2

オブジェクトが存在しないスーパークラスを持つクラス階層がありfbます (仮想クラスを試しましたが、仮想クラスからオブジェクトを初期化できないという問題が発生しました)。さらに、同じスロットを持つ 2 つのサブクラス ( foo、 ) があります。barここで、値に基づいてサブクラスの 1 つのオブジェクトを返すスーパークラスの初期化メソッドを使用して、新しいオブジェクトを作成したいと考えています。

setClass("fb", representation( x = "numeric"))

setClass("foo", contains = "fb")
setClass("bar", contains = "fb")

setMethod("initialize", "fb", function(.Object, x) {
    if (x < 5) class(.Object) <- "foo"
    else class(.Object) <- "bar"
    .Object@x <- x
    .Object
})

> new("fb", x = 3)
Error in initialize(value, ...) : 
  initialize method returned an object of class "foo" instead of the required class "fb"

明らかに (そしておそらく正当な理由で) R はそれを許可していません。新しいオブジェクトを作成するときに if-else コンストラクトを使用せずに、メソッド内で目的を達成する方法はありますか?

4

1 に答える 1

4

S4 は、線の内側に色を付けるのに役立ちます。したがって、fbクラスは仮想でinitializeなければならず、メソッドは のクラスを変更してはなりません.Objectfb条件付きインスタンス化を行う関数を作成する場合があります。

setClass("fb", representation( x = "numeric", "VIRTUAL"))
setClass("foo", contains = "fb")
setClass("bar", contains = "fb")

fb <-
    function(x)
{
    if (x < 5) new("foo", x=x)
    else new("bar", x=x)
}

fbユーザーにとってより便利なコンストラクターであり、クラス階層へのインターフェースをその実装から分離します。これは一般的に良いことと考えられています。

initializeそして、S4メソッドに対する暗黙の制約の価値があるのは、(クラス名でnew("foo")呼び出すが追加の引数なしで呼び出す) 動作する必要があることです (そうしないと、foo を拡張しようとすると失敗します)。newしたがって、初期化メソッドのパラダイムは次のようになります。

setMethod(initialize, "foo", function(.Object, ..., x=1) {
    .Object <- callNextMethod(.Object, ...)
    .Object@x <- x
    .Object
})

多くの場合 (この場合のように、 whereinitializeはスロットの割り当てを行っているだけです)、initialize メソッドはまったく必要ありません。の使用...、 の配置x(対応する への呼び出しで引数の名前を指定する必要があるnew)、およびデフォルト値の使用に注意してください。

于 2011-07-22T14:51:56.973 に答える