Thứ tự tra cứu phương thức
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 13 trên 57.
Với mỗi lần gọi, R duyệt qua vector lớp từ trái sang phải và chạy phương thức đầu tiên tìm thấy. Nếu không lớp nào có phương thức đó, R sẽ dùng phương thức mặc định. Các đối tượng khác nhau trong cùng một hệ phân cấp có thể dừng ở các cấp độ khác nhau:
move <- function(x) UseMethod("move")
move.animal <- function(x) "walks"
move.bird <- function(x) "flies"
move.default <- function(x) "stays"
penguin <- structure(list(), class = c("penguin", "bird", "animal"))
dog <- structure(list(), class = c("dog", "animal"))
rock <- structure(list(), class = "rock")
cat(move(penguin), move(dog), move(rock))Đầu ra:
flies walks staysLớp con ghi đè phương thức của lớp cha bằng cách định nghĩa phương thức riêng. Việc ghi đè chỉ ảnh hưởng đến lớp con và mọi lớp bên dưới nó; lớp cha và các lớp con khác vẫn giữ phương thức của lớp cha:
move <- function(x) UseMethod("move")
move.animal <- function(x) "walks"
move.bird <- function(x) "flies"
move.penguin <- function(x) "swims"
penguin <- structure(list(), class = c("penguin", "bird", "animal"))
sparrow <- structure(list(), class = c("bird", "animal"))
cat(move(penguin), move(sparrow))Đầu ra:
swims fliesMỗi hàm generic được tra cứu riêng. Một đối tượng có thể lấy sound() từ lớp của chính nó và move() từ lớp cha, còn một phương thức của lớp cha có thể gọi các hàm generic khác để chúng lại phân phối theo lớp con:
sound <- function(x) UseMethod("sound")
move <- function(x) UseMethod("move")
describe <- function(x) UseMethod("describe")
sound.animal <- function(x) "..."
sound.dog <- function(x) "woof"
move.animal <- function(x) "walks"
describe.animal <- function(x) paste(x$name, "says", sound(x), "and", move(x))
rex <- structure(list(name = "Rex"), class = c("dog", "animal"))
print(describe(rex))Đầu ra:
[1] "Rex says woof and walks"Với một đối tượng có thuộc tính lớp, cơ chế điều phối chỉ xét thuộc tính đó rồi đến phương thức mặc định. Bên trong, đối tượng vẫn là một danh sách, nhưng phương thức dành cho list không được thử:
size <- function(x) UseMethod("size")
size.list <- function(x) "a list"
size.default <- function(x) "default"
bag <- structure(list(1, 2), class = "bag")
cat(size(list(1, 2)), "/", size(bag))Đầu ra:
a list / defaultThử thách
DễHình vuông là hình chữ nhật có các cạnh bằng nhau. Trong Rectangle.R, hãy viết các phương thức area.rectangle(), perimeter.rectangle() và name.rectangle(), trả về rectangle 2x3. Trong Square.R, hãy hoàn thiện new_square(side), hàm này gọi new_rectangle() với lớp square, và chỉ ghi đè name() bằng name.square(), trả về square 2. Hình vuông phải dùng area() và perimeter() của hình chữ nhật.
Các hàm generic và new_rectangle() đã được cung cấp. Code có sẵn đọc các dòng gồm hai số (hình chữ nhật) hoặc một số (hình vuông) rồi in ra square 2: area 4, perimeter 8.
Code của bạn đặt trong Rectangle.R và Square.R. main.R chứa code đầu vào/đầu ra đã cung cấp và bạn không thể chỉnh sửa.
Tự làm thử
source("Rectangle.R")
source("Square.R")
# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
n <- as.numeric(strsplit(line, " ")[[1]])
s <- if (length(n) == 1) new_square(n[1]) else new_rectangle(n[1], n[2])
cat(name(s), ": area ", area(s), ", perimeter ", 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ênTự luyện tập: Trình biên dịch R online