2011-11-16 82 views
10

是否有可能在R引用類中包含私有成員字段。玩一些我在網上的例子: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 

我討厭我可以直接更新餘額的事實。也許,在我這個老純粹的面向對象中,我真的希望能夠平衡私人空間,至少在課堂外是不可設置的。

想法

+0

R6包/框架有私人領域和方法內置(並聲稱是更高性能)。 – petermeissner

回答

3

這個答案不適用於R> 3.00,所以不要使用它!

如前所述,您不能擁有私人會員字段。但是,如果您使用初始化方法,則餘額不會顯示爲字段。例如,

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 
2

R不是那種語言。沒有私人或公共的概念。

+0

我注意到有興趣的downvote。如果我有這個錯誤,那麼請告訴我如何。 –

+0

我認爲somene正在拍攝使者。 R中的類如果不允許我封裝和控制狀態,它的價值是什麼?或者表達方式不同,他們想要解決什麼問題(類) – akaphenom

+1

沒有訪問保護的OOP仍然有價值。我認爲只需要一個不同的思維模式。 –

2

爲了解決隱私問題,我創建了一個自己的類「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