nextMethod()로 확장하기
Coddy R 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 14번째.
자식 메서드는 부모의 작업에 약간의 작업을 더하는 경우가 많습니다. NextMethod()는 부모 메서드를 호출하므로, 자식은 새로 추가된 부분만 구현하면 됩니다. 관리자의 월급은 직원의 월급에 보너스를 더한 금액입니다:
pay <- function(x) UseMethod("pay")
pay.employee <- function(x) x$salary / 12
pay.manager <- function(x) NextMethod() + x$bonus / 12
m <- structure(list(salary = 60000, bonus = 12000), class = c("manager", "employee"))
e <- structure(list(salary = 36000), class = "employee")
cat(pay(e), pay(m))출력:
3000 6000NextMethod()는 여러 수준에 걸쳐 계속 작동합니다. 각 메서드는 자신의 부분을 추가하고, 자신 다음의 클래스에 처리를 넘깁니다:
pay <- function(x) UseMethod("pay")
pay.employee <- function(x) x$salary / 12
pay.manager <- function(x) NextMethod() + x$bonus / 12
pay.director <- function(x) NextMethod() + 500
d <- structure(list(salary = 120000, bonus = 24000),
class = c("director", "manager", "employee"))
print(pay(d))출력:
[1] 12500자식 메서드는 먼저 확인한 후, 확인이 통과된 경우에만 처리를 부모 메서드에 넘길 수도 있습니다. 부모 메서드는 전체 클래스 벡터를 포함하여 변경된 객체를 반환하므로, 결과는 여전히 저축 계좌입니다:
withdraw <- function(acc, amount) UseMethod("withdraw")
withdraw.account <- function(acc, amount) {
if (amount > acc$balance) stop("insufficient funds", call. = FALSE)
acc$balance <- acc$balance - amount
acc
}
withdraw.savings <- function(acc, amount) {
if (amount > 500) stop("savings limit is 500", call. = FALSE)
NextMethod()
}
s <- structure(list(balance = 1000), class = c("savings", "account"))
s <- withdraw(s, 200)
cat(s$balance, class(s))출력:
800 savings account생성자와 메서드는 동일한 방식으로 부모를 재사용합니다. new_manager()는 new_employee()를 호출하고, pay.manager()는 NextMethod()를 호출합니다. 직원 코드는 한 번만 작성하며 모든 하위 클래스가 이를 기반으로 구축됩니다:
new_manager <- function(name, salary, bonus) {
new_employee(name, salary, bonus = bonus, class = "manager") # 생성자를 재사용
}
pay.manager <- function(x) NextMethod() + x$bonus / 12 # 메서드를 재사용챌린지
쉬움계정과 저축 계정은 두 파일에 있습니다. Account.R에서 금액이 잔액보다 클 때 insufficient funds와 함께 중단하고, 그렇지 않으면 잔액이 줄어든 계정을 반환하는 withdraw.account(acc, amount)와 ada: 800을 반환하는 format.account()을 완성하세요. Savings.R에서는 금액이 500보다 클 때 savings limit is 500과 함께 중단하고, 그렇지 않으면 NextMethod()로 처리를 넘기는 withdraw.savings()와 NextMethod()을 호출하여 ada: 800 (savings)을 반환하는 format.savings()을 완성하세요.
call. = FALSE를 사용하세요. 제네릭과 생성자는 제공되어 있습니다. 제공된 코드는 savings ada 1000 또는 account bo 300을 읽은 다음 인출할 금액을 읽습니다. withdrew 200 또는 refused: 와 메시지를 출력하고, 마지막으로 형식이 지정된 계정을 출력합니다.
코드는 Account.R과 Savings.R에 작성하세요. main.R에는 제공된 입력/출력 코드가 들어 있으며 수정할 수 없습니다.
직접 해보기
source("Account.R")
source("Savings.R")
# 제공된 입력/출력 코드: 그대로 유지하세요
input <- suppressWarnings(readLines(file("stdin")))
p <- strsplit(input[1], " ")[[1]]
acc <- if (p[1] == "savings") new_savings(p[2], as.numeric(p[3])) else new_account(p[2], as.numeric(p[3]))
for (amount in as.numeric(input[-1])) {
acc <- tryCatch({
acc <- withdraw(acc, amount)
cat("withdrew ", amount, "\n", sep = "")
acc
}, error = function(e) {
cat("refused: ", conditionMessage(e), "\n", sep = "")
acc
})
}
cat(format(acc), "\n", sep = "")
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 R 컴파일러