Menu
CoddyTech

Memperluas dengan NextMethod

Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan R di Coddy. Pelajaran 14 dari 57.

Method pada child sering mengerjakan tugas parent ditambah sedikit lagi. NextMethod() memanggil method parent, jadi child hanya menambahkan hal yang baru. Gaji bulanan seorang manager adalah gaji seorang employee ditambah bonus:

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))

Output:

3000 6000

NextMethod() terus bekerja melewati beberapa tingkatan. Setiap method menambahkan bagiannya dan meneruskannya ke class setelah class-nya sendiri:

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))

Output:

[1] 12500

Method child juga dapat memeriksa terlebih dahulu dan meneruskan hanya jika pemeriksaan berhasil. Method milik induk mengembalikan object yang telah berubah beserta vektor class lengkapnya, sehingga hasilnya tetap berupa rekening tabungan:

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))

Output:

800 savings account

Konstruktor dan method menggunakan kembali parent dengan cara yang sama: new_manager() memanggil new_employee(), dan pay.manager() memanggil NextMethod(). Kode employee ditulis sekali dan setiap subclass dibangun berdasarkan kode tersebut:

new_manager <- function(name, salary, bonus) {
  new_employee(name, salary, bonus = bonus, class = "manager")   # gunakan kembali constructor
}
pay.manager <- function(x) NextMethod() + x$bonus / 12            # gunakan kembali method
challenge icon

Tantangan

Mudah

Account dan rekening tabungan berada di dua file. Di Account.R, lengkapi withdraw.account(acc, amount), yang berhenti dengan insufficient funds ketika jumlahnya melebihi saldo, dan jika tidak, mengembalikan account dengan saldo yang lebih rendah, serta format.account(), yang mengembalikan ada: 800. Di Savings.R, lengkapi withdraw.savings(), yang berhenti dengan savings limit is 500 untuk jumlah di atas 500 dan jika tidak, meneruskan pemanggilan dengan NextMethod(), serta format.savings(), yang mengembalikan ada: 800 (savings) dengan memanggil NextMethod().

Gunakan call. = FALSE. Fungsi generik dan konstruktor sudah disediakan. Kode yang disediakan membaca savings ada 1000 atau account bo 300, lalu jumlah yang akan ditarik; kode tersebut mencetak withdrew 200 atau refused: beserta pesannya, lalu mencetak account yang telah diformat.

Kodemu ditulis di Account.R dan Savings.R. main.R berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

source("Account.R")
source("Savings.R")

# Kode input/output yang disediakan: biarkan apa adanya
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 = "")
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler R online