77

Lập trình hướng đối tượng theo cách này hay cách khác là rất có thể trong R. Tuy nhiên, không giống như Python, có nhiều cách để đạt được hướng đối tượng:

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

Những khác biệt chính nào phân biệt 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ẽ đóng vai trò 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 đang 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à tài liệu tham khảo. Điểm thưởng để làm rõ cách thức các phương pháp này ánh xạ tới các thực tiễn OO tiêu chuẩn.

|
33

Lớp S3

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

Các lớp S4

Lớp tham khảo

nguyên sinh

  • 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 gọn gàng (nguyên mẫu, không phải lớp học), nhưng có vẻ khó khăn trong thực tế
  • Phiên bản tiếp theo của ggplot2 dường như đang di chuyển khỏi nó
  • Mô tả khái niệm và thực hiện

Các lớp R6

  • Tham khảo phụ
  • Không phụ thuộc vào các lớp S4
  • " Tạo một lớp R6 tương tự như lớp tham chiếu, ngoại trừ việc không cần tách các trường và phương thức và bạn không thể chỉ định các loại của các trường."
|
19

Chỉnh sửa vào ngày 3/8/12: Câu trả lời dưới đây trả lời một phần của câu hỏi được đăng ban đầu đã bị xóa. 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:

Làm thế nào để các phương thức OO khác nhau ánh xạ tới các phương thức OO tiêu chuẩn hơn được sử dụng trong ví dụ 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, về cách các phương pháp OO của R ánh xạ tới các phương thức OO tiêu chuẩn hơn. Như tôi đã nghĩ về điều này trong quá khứ, tôi đã trở lại nhiều lần với hai đoạn, một của Friedrich Leisch và một của John Chambers. Cả hai đều làm tốt công việc nói rõ tại sao lập trình giống OO trong R có hương vị khác với nhiều ngôn ngữ khác.

Đầu tiên, Friedrich Leisch, từ "Tạo gói R: Hướng dẫn" ( cảnh báo: PDF ):

S rất hiếm vì nó vừa tương tác vừa có hệ thống hướng đối tượng. Thiết kế các lớp rõ ràng là lập trình, nhưng để làm cho S 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 đó 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 (OOP) "thực" như lớp C ++ hoặc lớp Java và các định nghĩa phương thức được liên kết 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 đó là các đối tượng). Chúng tôi muốn các bổ sung gia tăng và tương tác như các phương thức do người dùng định nghĩa 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 di chuyển tại dấu nhắc dòng lệnh trong khi chúng tôi phân tích một 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, và mặc dù thỏa hiệp không bao giờ là tối ưu đối với tất cả các mục tiêu mà họ cố gắng đạt được, chúng thường hoạt động tốt một cách đáng ngạc nhiên trong thực tế.

Đoạn khác đến từ cuốn sách tuyệt vời "Phần mềm phân tích dữ liệu" của John Chambers . ( Liên kết đến đoạn trích dẫn ):

Mô hình lập trình OOP khác với ngôn ngữ S ở tất cả trừ đ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 và phương thức. Các định nghĩa phương thức trong một hệ thống OOP là cục bộ của lớp; không có yêu cầu rằng cùng tên cho một phương thức có nghĩa là điều tương tự đối với một lớp không liên quan. Ngược lại, các đị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 liên kết với chức năng chung. Các định nghĩa lớp nhập vào xác định lựa chọn phương thức, trực tiếp hoặc thông qua kế thừa. Các lập trình viên được sử dụng cho mô hình OOP đôi khi thất vọng hoặc bối rối rằng lập 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 dễ hiểu hơn khi có các chức năng có ý nghĩa và không thể chuyển thành phiên bản OOP.

|
14

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

#' 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", "jason@bryer.org")
    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("jbryer@excelsior.edu")
    test$getHistory()
    test$sendMail("test@domain.edu")
    test$getNumMessagesSent()

    test2 <- EmailClass("Nobody", "dontemailme@nowhere.com")
    test2
    test2$props
    test2$getHistory()
    test2$sendMail('nobody@exclesior.edu')

Đây là một liên kết đến một bài đăng trên blog mà tôi đã viết về cách tiếp cận này: http://bowder.org/2012/object-oriented-programming-in-r Tôi sẽ hoan nghênh các bình luận, phê bình và đề xuất cho phương pháp này vì tôi không bị thuyết phục bản thân tôi 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ó đã hoạt động rất tốt. Cụ thể, đối với gói makeR ( http://jbowder.github.com/makeR ) Tôi không muốn người dùng thay đổi trực tiếp các trường dữ liệu vì tôi cần đảm bảo rằng tệp XML đại diện cho trạng thái đối tượng của tôi sẽ được đồng bộ hóa. Điều này hoạt động 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.

|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.