2012-03-01 51 views
71

Object bằng cách này hay cách khác là rất nhiều khả năng trong R. Tuy nhiên, không giống như ví dụ Python, có rất nhiều cách để đạt được định hướng đối tượng:R và hướng đối tượng lập trình lập trình hướng

Câu hỏi của tôi là:

Điều gì khác biệt chính khác biệt giữa các cách lập trình OO này trong R?

Lý tưởng nhất là các câu trả lời ở đây sẽ là tài liệu tham khảo cho các lập trình viên R đang cố gắng quyết định phương pháp lập trình OO nào phù hợp nhất với nhu cầu của họ.

Như vậy, tôi yêu cầu chi tiết, trình bày một cách khách quan, dựa trên kinh nghiệm và được hỗ trợ với các sự kiện và tham chiếu. Điểm thưởng để làm rõ cách các phương pháp này ánh xạ tới thực tiễn OO chuẩn.

+1

Thông tin về lớp tham chiếu: http://stackoverflow.com/questions/5137199/what-is-the-significance-of-the-new-reference-classes –

+0

Cảm ơn, bạn có thể đăng lại liên kết dưới dạng câu trả lời không? Sẽ rất tuyệt nếu bạn có thể bao gồm một bản tóm tắt nhỏ về các lớp Tham chiếu là gì và tại sao chúng lại thích hợp hơn với các lớp S3/S4. –

+0

Một con chim nhỏ thì thầm vào tai tôi rằng một cuốn sách về điều này sẽ được sắp tới bởi John Chambers. Nhưng đừng nói với bất cứ ai tôi đã nói rằng ... ;-) –

Trả lời

32

lớp S3

  • Không thực sự đối tượng, nhiều hơn một quy ước đặt tên
  • Dựa xung quanh. cú pháp: Ví dụ: cho in ấn, print gọi print.lmprint.anova, vv Và nếu không tìm thấy, print.default

S4 lớp

Reference lớp học

proto

  • ggplot2 ban đầu được viết bằng proto, nhưng cuối cùng sẽ được viết lại bằng S3.
  • khái niệm Neat (nguyên mẫu, không phải lớp), nhưng dường như khó khăn trong thực tế
  • phiên bản tiếp theo của ggplot2 dường như được di chuyển ra khỏi nó
  • Description of the concept and implementation

lớp R6

  • By-reference
  • Không phụ thuộc vào lớp S4
  • "Creating lớp R6 tương tự như lớp tham chiếu, ngoại trừ việc không cần phải tách biệt các trường và phương thức và bạn không thể chỉ định loại trường".
+1

Hãy chỉnh sửa nếu bạn có những khác biệt khác để thêm vào. m sẽ không khóc nếu nó trở thành CW :-) –

+3

đừng quên 'thư viện (" vận may "); fortune ("strait") ' –

+1

Thảo luận về các lớp học S4 tại đây: http://stackoverflow.com/questions/3602154/when-does-it-pay-off-to-use-s4-methods-in-r-programming . Cảm giác chung dường như là họ gặp nhiều rắc rối hơn sau đó họ mang lại lợi thế. –

19

Chỉnh sửa trên 3/8/12: Câu trả lời dưới đây phản ứng với một mảnh của câu hỏi gửi ban đầu mà từ đó đã được gỡ bỏ. Tôi đã sao chép nó bên dưới, để cung cấp ngữ cảnh cho câu trả lời của tôi:

Các phương thức OO khác nhau ánh xạ tới các phương pháp OO chuẩn được sử dụng như thế nào. Java hoặc Python?


đóng góp của tôi liên quan đến câu hỏi thứ hai của bạn, khoảng cách phương pháp OO R của bản đồ phương pháp OO tiêu chuẩn hơn. Như tôi đã nghĩ về điều này trong quá khứ, tôi đã trở lại một lần nữa và một lần nữa để hai đoạn, một của Friedrich Leisch, và một bởi John Chambers. Cả hai đều làm một công việc tốt về khớp nối tại sao lập trình giống như OO trong R có một hương vị khác với nhiều ngôn ngữ khác.

Thứ nhất, Friedrich Leisch, từ "Gói Tạo R: A Hướng dẫn" (warning: PDF):

S là hiếm bởi vì nó là cả tương tác và có một hệ thống hướng đối tượng. Việc thiết kế các lớp rõ ràng là lập trình, nhưng để làm cho S trở nên hữu ích như một môi trường phân tích dữ liệu tương tác, nó có ý nghĩa rằng nó là một ngôn ngữ chức năng. Trong các ngôn ngữ lập trình hướng đối tượng "thực" (OOP) như C++ hoặc các lớp Java và các định nghĩa phương thức được ràng buộc chặt chẽ với nhau, các phương thức là một phần của các lớp (và do đó các đối tượng). Chúng tôi muốn bổ sung gia tăng và tương tác như phương pháp do người dùng xác định cho các lớp được xác định trước. Những bổ sung này có thể được thực hiện tại bất kỳ thời điểm nào, ngay cả khi đang bay tại dấu nhắc dòng lệnh trong khi chúng tôi phân tích tập dữ liệu. S cố gắng thỏa hiệp giữa định hướng đối tượng và sử dụng tương tác, mặc dù sự thỏa hiệp không bao giờ tối ưu đối với tất cả các mục tiêu mà họ cố gắng tiếp cận, họ thường làm việc rất tốt trong thực tế.

Đoạn văn khác đến từ cuốn sách tuyệt vời của John Chambers "Software for Data Analysis". (Link to quoted passage):

Các mô hình lập trình OOP khác với ngôn ngữ S trong tất cả nhưng điểm đầu tiên, mặc dù S và một số ngôn ngữ chức năng khác hỗ trợ các lớp học và phương pháp. Các định nghĩa phương thức trong một hệ thống OOP là cục bộ cho lớp; không có yêu cầu trùng tên cho phương thức có nghĩa là cùng một điều cho một lớp không liên quan. Ngược lại, định nghĩa phương thức trong R không nằm trong định nghĩa lớp; về mặt khái niệm, chúng được kết hợp với hàm chung.Định nghĩa lớp học nhập vào việc xác định lựa chọn phương pháp, trực tiếp hoặc thông qua kế thừa. Các lập trình viên sử dụng mô hình OOP đôi khi là thất vọng hoặc bối rối rằng chương trình của họ không chuyển trực tiếp sang R, nhưng không thể. Việc sử dụng chức năng của các phương thức phức tạp hơn nhưng cũng cần thêm để có các hàm có ý nghĩa và không thể giảm xuống phiên bản OOOP.

13

S3 và S4 có vẻ là phương pháp chính thức (tức là được xây dựng) cho lập trình OO. Tôi đã bắt đầu sử dụng một sự kết hợp của S3 với các hàm được nhúng trong hàm/phương thức của hàm dựng. Mục tiêu của tôi là có một cú pháp kiểu $ method() đối tượng để tôi có các trường bán riêng. Tôi nói bán tư nhân bởi vì không có cách nào thực sự che giấu chúng (theo như tôi biết). Dưới đây là một ví dụ đơn giản mà không thực sự làm bất cứ điều gì:

#' Constructor 
EmailClass <- function(name, email) { 
    nc = list(
     name = name, 
     email = email, 
     get = function(x) nc[[x]], 
     set = function(x, value) nc[[x]] <<- value, 
     props = list(), 
     history = list(), 
     getHistory = function() return(nc$history), 
     getNumMessagesSent = function() return(length(nc$history)) 
    ) 
    #Add a few more methods 
    nc$sendMail = function(to) { 
     cat(paste("Sending mail to", to, 'from', nc$email)) 
     h <- nc$history 
     h[[(length(h)+1)]] <- list(to=to, timestamp=Sys.time()) 
     assign('history', h, envir=nc) 
    } 
    nc$addProp = function(name, value) { 
     p <- nc$props 
     p[[name]] <- value 
     assign('props', p, envir=nc) 
    } 
    nc <- list2env(nc) 
    class(nc) <- "EmailClass" 
    return(nc) 
} 

#' Define S3 generic method for the print function. 
print.EmailClass <- function(x) { 
    if(class(x) != "EmailClass") stop(); 
    cat(paste(x$get("name"), "'s email address is ", x$get("email"), sep='')) 
} 

Và một số mã kiểm tra:

test <- EmailClass(name="Jason", "[email protected]") 
    test$addProp('hello', 'world') 
    test$props 
    test 
    class(test) 
    str(test) 
    test$get("name") 
    test$get("email") 
    test$set("name", "Heather") 
    test$get("name") 
    test 
    test$sendMail("[email protected]") 
    test$getHistory() 
    test$sendMail("[email protected]") 
    test$getNumMessagesSent() 

    test2 <- EmailClass("Nobody", "[email protected]") 
    test2 
    test2$props 
    test2$getHistory() 
    test2$sendMail('[email protected]') 

đây là một liên kết đến một bài viết trên blog, tôi đã viết về phương pháp này: http://bryer.org/2012/object-oriented-programming-in-r tôi sẽ chào đón nhận xét, phê bình và gợi ý cho phương pháp này vì tôi không thuyết phục bản thân mình nếu đây là cách tiếp cận tốt nhất. Tuy nhiên, đối với vấn đề tôi đã cố gắng để giải quyết nó đã làm việc tuyệt vời. Cụ thể, đối với gói makeR (http://jbryer.github.com/makeR), tôi không muốn người dùng thay đổi trường dữ liệu trực tiếp vì tôi cần đảm bảo rằng tệp XML đại diện cho trạng thái của đối tượng của tôi sẽ được đồng bộ hóa. Điều này làm việc hoàn hảo miễn là người dùng tuân thủ các quy tắc tôi phác thảo trong tài liệu.

+10

Bạn là loại tái phát minh các lớp tham khảo "bằng tay" với mã trên ... Nó chỉ làm cho điều khá mỏng manh hơn một chút. –

+0

Cảm ơn Simon. Tôi đã không biết về ReferenceClasses cho đến sau khi tôi đăng bài này. – jbryer

Các vấn đề liên quan