12

R参照クラス内にプライベートメンバーフィールドを持つことは可能ですか? 私が持っているいくつかのオンラインの例で遊んでいます:

> Account <- setRefClass(    "ref_Account"
>      , fields = list(
>       number = "character"
>       , balance ="numeric")
>      , methods = list( 
>     deposit <- function(amount) {
>       if(amount < 0)   {
>         stop("deposits must be positive")
>       }
>       balance <<- balance + amount
>     }
>     , withdraw <- function(amount) {
>       if(amount < 0)   {
>         stop("withdrawls must be positive")
>       }
>       balance <<- balance - amount
>     }       
>   ) )
> 
> 
> tb <- Account$new(balance=50.75, number="baml-029873") tb$balance
> tb$balance <- 12 
> tb$balance

残高を直接更新できるという事実が嫌いです。おそらく、私の中の古い純粋な OO は、バランスを非公開にして、少なくともクラスの外から設定できないようにしたいと思っています。

考え

4

3 に答える 3

4

$プライバシーの問題を解決するために、オブジェクトにアクセスするための新しいメソッド、つまりとを持つ独自のクラス「Private」を作成します[[。クライアントが「プライベート」メンバーにアクセスしようとすると、これらのメソッドはエラーをスローします。プライベートメンバーは名前(先頭のピリオド)で識別されます。参照オブジェクトは R の環境であるため、これを回避できますが、現時点ではこれが私の解決策であり、クラスによって提供される get/set メソッドを使用する方が便利だと思います。したがって、これは質問に対する「クラス外から設定するのが難しい」ソリューションです。

これを R パッケージ内に整理したので、次のコードはそのパッケージを利用し、上記の例を変更して、への割り当てtb$.balanceでエラーが発生するようにします。Classまた、単なるラッパーである関数も使用しているsetRefClassため、これはメソッドパッケージによって提供され、質問で使用されている R の参照クラスの範囲内にあります。

devtools::install_github("wahani/aoos")
library("aoos")

Account <- defineRefClass({
    Class <- "Account"
    contains <- "Private"

    number <- "character"
    .balance <- "numeric"

    deposit <- function(amount) {
        if(amount < 0) stop("deposits must be positive")
        .balance <<- .balance + amount
    }

    withdraw <- function(amount) {
        if(amount < 0) stop("withdrawls must be positive")
        .balance <<- .balance - amount
    }
})

tb <- Account(.balance = 50.75, number = "baml-029873") 
tb$.balance # error
tb$.balance <- 12 # error
于 2015-03-23T15:24:15.460 に答える
3

この回答はR>3.00では機能しないため、使用しないでください。

すでに述べたように、プライベートメンバーフィールドを持つことはできません。ただし、initializeメソッドを使用する場合、残高はフィールドとして表示されません。例えば、

Account = setRefClass("ref_Account", 
                       fields = list(number = "character"),
                       methods = list(
                           initialize = function(balance, number) {
                               .self$number = number
                               .self$balance = balance
                           })

前と同じように、インスタンスを作成します。

tb <- Account$new(balance=50.75, number="baml-0029873")
##No balance
tb

Reference class object of class "ref_Account"
Field "number":
[1] "baml-0029873"

私が言ったように、あなたはまだすることができるので、それは本当にプライベートではありません:

R> tb$balance
[1] 50.75
R> tb$balance = 12 
R> tb$balance
[1] 12
于 2012-11-08T11:09:45.097 に答える