Điều phối theo hai đối số
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 29 trên 57.
Generic S4 có thể chọn phương thức dựa trên lớp của nhiều đối số. Chữ ký liệt kê một lớp cho mỗi đối số, vì vậy mỗi cặp lớp có thể có phương thức riêng:
setClass("Asteroid", slots = c(size = "numeric"))
setClass("Ship", slots = c(name = "character"))
invisible(setGeneric("collide", function(a, b) standardGeneric("collide")))
setMethod("collide", signature("Asteroid", "Ship"), function(a, b) paste(b@name, "is hit"))
setMethod("collide", signature("Ship", "Ship"), function(a, b) "two ships bump")
rock <- new("Asteroid", size = 3)
enterprise <- new("Ship", name = "Enterprise")
print(collide(rock, enterprise))
print(collide(enterprise, enterprise))Đầu ra:
[1] "Enterprise is hit"
[1] "two ships bump"Lớp "ANY" khớp với mọi lớp. Phương thức cho signature("ANY", "ANY") là phương án dự phòng, chạy khi không có cặp cụ thể hơn nào phù hợp:
setClass("Ship", slots = c(name = "character"))
invisible(setGeneric("collide", function(a, b) standardGeneric("collide")))
setMethod("collide", signature("Ship", "Ship"), function(a, b) "two ships bump")
setMethod("collide", signature("ANY", "ANY"), function(a, b) "nothing happens")
s <- new("Ship", name = "A")
cat(collide(s, s), "/", collide(s, 42), "/", collide("x", "y"))Đầu ra:
two ships bump / nothing happens / nothing happensThứ tự của các đối số rất quan trọng: signature("A", "B") và signature("B", "A") là các phương thức khác nhau. Các lớp cơ bản như numeric và character cũng có thể xuất hiện trong chữ ký:
invisible(setGeneric("join", function(x, y) standardGeneric("join")))
setMethod("join", signature("character", "numeric"), function(x, y) paste(x, "number", y))
setMethod("join", signature("numeric", "character"), function(x, y) paste(y, "after number", x))
print(join("item", 3))
print(join(3, "item"))Đầu ra:
[1] "item number 3"
[1] "item after number 3"Lớp "missing" trong chữ ký khớp với một đối số hoàn toàn không được cung cấp, vì vậy một hàm generic có thể hỗ trợ cả dạng ngắn và dạng dài:
invisible(setGeneric("greet", function(name, greeting) standardGeneric("greet")))
setMethod("greet", signature("character", "missing"), function(name, greeting) paste("Hello,", name))
setMethod("greet", signature("character", "character"), function(name, greeting) paste0(greeting, ", ", name))
print(greet("Ada"))
print(greet("Ada", "Good morning"))Đầu ra:
[1] "Hello, Ada"
[1] "Good morning, Ada"Thử thách
DễGiá vận chuyển phụ thuộc vào món hàng và khu vực. Các lớp được khai báo trong Item.R (Letter, Box, mỗi lớp có một slot kg) và Zone.R (Domestic, Abroad, mỗi lớp có một slot name). Trong Rates.R, hãy tạo hàm tổng quát shipping(item, zone) và một phương thức cho mỗi cặp:
Lettertrong nước: 1; nước ngoài: 3.Boxtrong nước: 5 cộng 2 cho mỗi kg; nước ngoài: 12 cộng 4 cho mỗi kg.- Mọi cặp khác: dừng lại với
no rate for this item and zone(dùngcall. = FALSE).
Code được cung cấp đọc các dòng box home 2.5 (món hàng, khu vực, kg), trong đó các từ không xác định vẫn là văn bản thông thường, rồi in ra box to home: 10.00 hoặc error: cùng thông báo lỗi.
Code của bạn nằm trong Item.R, Zone.R và Rates.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("Item.R")
source("Zone.R")
source("Rates.R")
# Đoạn code đầu vào/đầu ra đã có sẵn: giữ nguyên
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
kg <- as.numeric(p[3])
item <- switch(p[1], letter = new("Letter", kg = kg), box = new("Box", kg = kg), kg)
zone <- switch(p[2], home = new("Domestic", name = "home"), abroad = new("Abroad", name = "abroad"), p[2])
out <- tryCatch(sprintf("%s to %s: %.2f", p[1], p[2], shipping(item, zone)),
error = function(e) paste("error:", conditionMessage(e)))
cat(out, "\n", sep = "")
}
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
1Kiến thức cơ bản về S3
Làm việc với tệpDanh sách với một lớpHàm khởi tạoPhương thức in ra và định dạngTrình xác thực và hàm hỗ trợÔn tập: nhiệt độ4Tính đóng gói trong R
Closure dưới dạng đối tượngMôi trường dưới dạng đối tượngHàm truy cậpBảo vệ trạng tháiÔn tập: đồng hồ tính phí đỗ xe2S3, hàm generic và phương thức
Hàm generic và UseMethodPhương thức mặc địnhPhương thức cho hàm generic cơ sởCơ bản về NextMethodÔn tập: diện tích hình5Các lớp S4
Định nghĩa lớp S4Slot và quyền truy cậpKiểm tra tính hợp lệPhương thức showÔn tập: Danh mục sản phẩm3S3 Tính kế thừa
Vector lớpThứ tự tra cứu phương thứcMở rộng với NextMethodKiểm tra với inherits()Ôn tập, tính lương nhân viên6S4 Generics và phương thức
Tạo GenericsPhương thức cho kiểu dựng sẵnĐiều phối theo hai đối sốsetValidity và validObjectÔn tập: tiền và tiền tệTự luyện tập: Trình biên dịch R online