2011-11-16 41 views
10

Có thể có các trường thành viên riêng bên trong lớp tham chiếu R không. Chơi với một số ví dụ trực tuyến tôi có:Các Thành viên Riêng tư trong R Lớp Tham chiếu

> 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 

Tôi ghét thực tế tôi có thể cập nhật số dư trực tiếp. Có lẽ OO tinh khiết cũ trong tôi, tôi thực sự muốn có thể làm cho sự cân bằng riêng tư, ít nhất là không thể định cư từ bên ngoài lớp học.

Suy nghĩ

+0

Gói/khung R6 có các trường và phương thức riêng tư được xây dựng (và được cho là có hiệu suất cao hơn). – petermeissner

Trả lời

3

Câu trả lời này không hoạt động với R> 3,00, vì vậy đừng sử dụng!

Như đã đề cập, bạn không thể có trường thành viên riêng tư. Tuy nhiên, nếu bạn sử dụng phương thức khởi tạo, thì số dư không được hiển thị dưới dạng một trường. Ví dụ,

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

Như trước đây, chúng ta sẽ tạo một ví dụ:

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

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

Như tôi đã đề cập, nó không phải là thực sự tin, vì bạn vẫn có thể làm:

R> tb$balance 
[1] 50.75 
R> tb$balance = 12 
R> tb$balance 
[1] 12 
2

R không phải là loại ngôn ngữ đó. Không có khái niệm riêng tư hoặc công khai.

+0

Tôi lưu ý phiếu giảm giá có lãi. Nếu tôi đã sai thì xin hãy cho tôi biết làm thế nào. –

+0

Tôi nghĩ rằng somene đang quay người đưa tin. Giá trị của các lớp trong vòng R là gì nếu chúng không cho phép tôi đóng gói và kiểm soát trạng thái? Hoặc nói cách khác là họ (lớp) nhằm giải quyết – akaphenom

+1

Vẫn còn giá trị trong OOP mà không cần bảo vệ truy cập. Tôi nghĩ người ta chỉ cần một suy nghĩ khác. –

2

Để giải quyết vấn đề bảo mật, tôi tạo một lớp riêng, "Riêng tư", có phương pháp mới để truy cập đối tượng, tức là $[[. Những phương pháp này sẽ ném một lỗi nếu khách hàng cố truy cập thành viên 'riêng tư'. Thành viên riêng được xác định theo tên (giai đoạn dẫn đầu). Như tham chiếu Các đối tượng là môi trường trong R có thể làm việc xung quanh điều này, nhưng nó là giải pháp của tôi vào lúc này và tôi nghĩ thuận tiện hơn khi sử dụng các phương thức get/set do lớp cung cấp. Vì vậy, đây là giải pháp “khó tính từ bên ngoài” cho câu hỏi.

Tôi đã tổ chức điều này bên trong gói R nên mã sau đây sử dụng gói đó và sửa đổi ví dụ trên sao cho phép gán cho tb$.balance gây lỗi. Tôi cũng sử dụng hàm Class mà chỉ là một trình bao bọc xung quanh setRefClass vì vậy điều này vẫn nằm trong phạm vi các lớp tham chiếu của R được cung cấp bởi gói phương thức và được sử dụng trong câu hỏi.

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 
Các vấn đề liên quan