Tạo Generics
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 27 trên 57.
Bạn tạo generic S4 bằng setGeneric(). Phần thân hàm của nó là standardGeneric("name"), phiên bản tương đương trong S4 của UseMethod(). setGeneric() trả về tên của generic, tên này sẽ được in ra khi bạn gọi hàm ở cấp cao nhất:
setGeneric("area", function(shape) standardGeneric("area"))Đầu ra:
[1] "area"Bọc lời gọi trong invisible() để ẩn dòng đó khỏi đầu ra. Tiếp theo, setMethod("area", "Circle", ...) thêm phương thức cho một lớp:
setClass("Circle", slots = c(r = "numeric"))
setClass("Square", slots = c(side = "numeric"))
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
setMethod("area", "Square", function(shape) shape@side^2)
cat(area(new("Circle", r = 1)), area(new("Square", side = 3)))Đầu ra:
3.141593 9Phương thức có cùng các đối số với hàm generic. Khi hàm generic có ..., phương thức có thể thêm các đối số có tên riêng sau đó:
setClass("Circle", slots = c(r = "numeric"))
invisible(setGeneric("describe", function(x, ...) standardGeneric("describe")))
setMethod("describe", "Circle", function(x, ..., digits = 2) {
paste("circle of area", round(pi * x@r^2, digits))
})
c1 <- new("Circle", r = 2)
print(describe(c1))
print(describe(c1, digits = 4))Đầu ra:
[1] "circle of area 12.57"
[1] "circle of area 12.5664"setMethod() cần generic đã tồn tại, vì vậy tệp có setGeneric() được nạp trước. Lệnh gọi cho một lớp không có phương thức sẽ dừng và báo lỗi nêu rõ chữ ký:
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setClass("Circle", slots = c(r = "numeric"))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
area(42)Đầu ra:
Error: unable to find an inherited method for function ‘area’ for signature ‘shape = "numeric"’
Execution haltedThử thách
DễCác hình là lớp S4 trong ba tệp. Trong Shape.R, hãy tạo các hàm tổng quát area(shape) và perimeter(shape) bằng setGeneric(), bọc chúng trong invisible(). Trong Circle.R và Square.R, các lớp đã được khai báo; hãy thêm các phương thức area và perimeter cho từng lớp bằng setMethod().
Code được cung cấp đọc các dòng circle 2 hoặc square 3 và in ra circle: area 12.57, perimeter 12.57.
Code của bạn nằm trong Shape.R, Circle.R và Square.R. main.R chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa.
Tự làm thử
source("Shape.R")
source("Circle.R")
source("Square.R")
# Đoạn code đầu vào/đầu ra đã cho: giữ nguyên
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
s <- if (p[1] == "circle") new("Circle", r = as.numeric(p[2])) else new("Square", side = as.numeric(p[2]))
cat(sprintf("%s: area %.2f, perimeter %.2f", p[1], area(s), perimeter(s)), "\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