Menu
Coddy logo textTech

NextMethod ile Genişletme

Coddy'nin R Journey'sinin Nesne Tabanlı Programlama bölümünün bir parçası. Ders 14 / 57.

Bir alt sınıf yöntemi genellikle üst sınıfın işini yapar ve üzerine biraz daha ekler. NextMethod() üst sınıf yöntemini çağırır; böylece alt sınıf yalnızca yeni olanı ekler. Bir yöneticinin aylık ücreti, çalışanın ücretine primin eklenmiş hâlidir:

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

Çıktı:

3000 6000

NextMethod() birkaç seviye boyunca çalışmaya devam eder. Her yöntem kendi kısmını ekler ve ardından kendi sınıfından sonraki sınıfa devreder:

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

Çıktı:

[1] 12500

Bir alt yöntem de önce kontrol yapabilir ve yalnızca kontrol başarılı olduğunda devri üst yönteme bırakabilir. Üst yöntemin yöntemi, değiştirilen nesneyi tam sınıf vektörüyle döndürür; bu nedenle sonuç hâlâ bir tasarruf hesabıdır:

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

Çıktı:

800 savings account

Yapıcılar ve metotlar üst sınıfı aynı şekilde yeniden kullanır: new_manager(), new_employee() çağırır ve pay.manager(), NextMethod() çağırır. Çalışan kodu bir kez yazılır ve her alt sınıf onun üzerine kurulur:

new_manager <- function(name, salary, bonus) {
  new_employee(name, salary, bonus = bonus, class = "manager")   # yapıcıyı yeniden kullan
}
pay.manager <- function(x) NextMethod() + x$bonus / 12            # metodu yeniden kullan
challenge icon

Görev

Kolay

Hesaplar ve tasarruf hesapları iki dosyada bulunur. Account.R içinde, miktar bakiyeden yüksek olduğunda insufficient funds ile duran, aksi takdirde hesabı daha düşük bakiyeyle döndüren withdraw.account(acc, amount) işlevini ve ada: 800 döndüren format.account() işlevini tamamlayın. Savings.R içinde, 500'den yüksek miktarlar için savings limit is 500 ile duran ve aksi takdirde NextMethod() ile devam eden withdraw.savings() işlevini ve NextMethod() çağırarak ada: 800 (savings) döndüren format.savings() işlevini tamamlayın.

call. = FALSE kullanın. Generic işlev ve kurucular verilmiştir. Sağlanan kod, savings ada 1000 veya account bo 300 ifadelerini, ardından çekilecek miktarları okur; withdrew 200 ya da refused: ve mesajı yazdırır ve son olarak biçimlendirilmiş hesabı yazdırır.

Kodunuz Account.R ve Savings.R dosyalarına yazılmalıdır. main.R sağlanan giriş/çıkış kodunu içerir ve düzenlenemez.

Kendin dene

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

# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
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 iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Tabanlı Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online R derleyicisi