Menu
CoddyTech

Phương thức cho kiểu dựng sẵn

Thuộc phần Lập trình hướng đối tượng trong hành trình R của Coddy. Bài học 28 trên 57.

setMethod() cũng thêm các phương thức S4 vào những hàm cơ sở như length() và summary(). Hàm cơ sở vẫn hoạt động với mọi thứ khác, còn lớp của bạn có hành vi riêng:

setClass("Playlist", slots = c(name = "character", songs = "character"))
setMethod("length", "Playlist", function(x) length(x@songs))
pl <- new("Playlist", name = "gym", songs = c("a", "b", "c"))
print(length(pl))
print(length(c(1, 2)))

Đầu ra:

[1] 3
[1] 2

Các toán tử cũng là hàm generic. Một phương thức cho + ghi tên lớp của cả hai vế trong signature(). Hai đối số được gọi là e1 và e2:

setClass("Money", slots = c(amount = "numeric"))
setMethod("show", "Money", function(object) cat(sprintf("%.2f", object@amount), "\n"))
setMethod("+", signature("Money", "Money"), function(e1, e2) {
  new("Money", amount = e1@amount + e2@amount)
})
new("Money", amount = 2.5) + new("Money", amount = 4)

Đầu ra:

6.50 

generic nhóm Arith đại diện cho +, -, *, /, ^ và các toán tử còn lại cùng lúc. Bên trong phương thức của nó, callGeneric() lặp lại toán tử đã dùng trên các giá trị bạn truyền vào:

setClass("Money", slots = c(amount = "numeric"))
setMethod("Arith", signature("Money", "numeric"), function(e1, e2) {
  new("Money", amount = callGeneric(e1@amount, e2))
})
m <- new("Money", amount = 10)
cat((m * 3)@amount, (m / 4)@amount, (m - 1)@amount)

Đầu ra:

30 2.5 9

Generic nhóm Compare bao gồm ==, <, > và các toán tử khác. Phương thức của nó trả về giá trị mà callGeneric() trả về cho các slot, một giá trị logic:

setClass("Money", slots = c(amount = "numeric"))
setMethod("Compare", signature("Money", "Money"), function(e1, e2) {
  callGeneric(e1@amount, e2@amount)
})
a <- new("Money", amount = 5)
b <- new("Money", amount = 8)
cat(a < b, a == b, a >= b)

Đầu ra:

TRUE FALSE FALSE
challenge icon

Thử thách

Dễ

Lớp Money trong Money.R có các slot amount (số) và currency (ký tự). Hãy thêm bốn phương thức:

  • show() in ra 12.50 EUR và một dòng mới;
  • + cho hai đối tượng Money trả về tổng của chúng, hoặc dừng với cannot add EUR and USD (dùng call. = FALSE) khi đơn vị tiền tệ khác nhau;
  • * cho Money và một số trả về số tiền đã nhân theo tỷ lệ;
  • == cho hai đối tượng Money có giá trị là TRUE khi cả số tiền và đơn vị tiền tệ đều bằng nhau.

Code được cung cấp đọc các dòng 10:EUR + 2.5:EUR, 4:USD * 3 hoặc 1:EUR == 1:EUR rồi in ra kết quả hoặc error: cùng thông báo.

Code của bạn nằm trong Money.R. main.R chứa code đầu vào/đầu ra được cung cấp và không thể chỉnh sửa.

Tự làm thử

source("Money.R")

# Đoạn code đầu vào/đầu ra đã cho: giữ nguyên
input <- suppressWarnings(readLines(file("stdin")))
parse_money <- function(t) {
  p <- strsplit(t, ":")[[1]]
  new("Money", amount = as.numeric(p[1]), currency = p[2])
}
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  a <- parse_money(p[1])
  tryCatch({
    if (p[2] == "+") print(a + parse_money(p[3]))
    if (p[2] == "*") print(a * as.numeric(p[3]))
    if (p[2] == "==") cat(a == parse_money(p[3]), "\n", sep = "")
  }, error = function(e) cat("error: ", conditionMessage(e), "\n", sep = ""))
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch R online