Menu
Coddy logo textTech

callNextMethod

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

Bir S4 yöntemi içinde callNextMethod(), aynı bağımsalarla üst sınıfın yöntemini çağırır ve sonucunu döndürür. Alt sınıf yöntemi, ebeveynin yanıtını tekrarlamak yerine onun üzerine ekleme yapar:

setClass("Employee", slots = c(name = "character", salary = "numeric"))
setClass("Manager", contains = "Employee", slots = c(reports = "numeric"))
invisible(setGeneric("describe", function(x) standardGeneric("describe")))
setMethod("describe", "Employee", function(x) paste(x@name, "earns", x@salary))
setMethod("describe", "Manager", function(x) paste(callNextMethod(), "and manages", x@reports))
print(describe(new("Manager", name = "Ada", salary = 60000, reports = 4)))

Çıktı:

[1] "Ada earns 60000 and manages 4"

show() için de çalışır: alt sınıf, üst sınıfın satırlarını ve ardından kendi satırlarını yazdırır:

setClass("Employee", slots = c(name = "character"))
setClass("Manager", contains = "Employee", slots = c(reports = "numeric"))
setMethod("show", "Employee", function(object) cat("Employee:", object@name, "\n"))
setMethod("show", "Manager", function(object) {
  callNextMethod()
  cat("Reports:", object@reports, "\n")
})
new("Manager", name = "Ada", reports = 4)

Çıktı:

Employee: Ada 
Reports: 4 

new(), genel initialize() işlevini çağırır. Bunun için yazılan bir metot, diğerlerinden elde edilen yuvaları doldurabilir. Önce callNextMethod(.Object, ...) çağrısını yapar; böylece normal kurulum ve geçerlilik kontrolü yine gerçekleşir:

setClass("Order", slots = c(prices = "numeric", total = "numeric"))
setMethod("initialize", "Order", function(.Object, ...) {
  .Object <- callNextMethod(.Object, ...)
  .Object@total <- sum(.Object@prices)
  .Object
})
o <- new("Order", prices = c(2.5, 4, 1))
print(o@total)

Çıktı:

[1] 7.5

S3'teki NextMethod() gibi, callNextMethod() birkaç seviye boyunca zincirleme ilerler ve her sınıf kendi katkısını ekler:

setClass("Ticket", slots = c(base = "numeric"))
setClass("Vip", contains = "Ticket")
setClass("Backstage", contains = "Vip")
invisible(setGeneric("price", function(t) standardGeneric("price")))
setMethod("price", "Ticket", function(t) t@base)
setMethod("price", "Vip", function(t) callNextMethod() * 2)
setMethod("price", "Backstage", function(t) callNextMethod() + 50)
cat(price(new("Ticket", base = 30)), price(new("Vip", base = 30)), price(new("Backstage", base = 30)))

Çıktı:

30 60 110
challenge icon

Görev

Kolay

Biletler, her biri kendi dosyasında olmak üzere üç seviyeye ayrılır. Sınıflar ve genel price() tanımlanmıştır. Metotları ekleyin:

  • Ticket.R: price() temel fiyattır; show(), Ticket for gala ifadesini ve yeni bir satırı yazdırır.
  • Vip.R: price(), bilet fiyatının 1.5 katıdır; show(), bilet satırını ve ardından VIP lounge access ifadesini yazdırır.
  • Backstage.R: price(), VIP fiyatına 50 eklenmiş halidir; show(), VIP satırlarını ve ardından Backstage pass ifadesini yazdırır.

Alt sınıf metotlarında callNextMethod() kullanın. Sağlanan kod, vip gala 80 satırlarını (seviye, etkinlik, temel fiyat) okur ve her bileti ve fiyatını yazdırır.

Kodunuz Ticket.R, Vip.R ve Backstage.R dosyalarına gider. main.R, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

source("Ticket.R")
source("Vip.R")
source("Backstage.R")

# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  base <- as.numeric(p[3])
  t <- switch(p[1],
    standard = new("Ticket", event = p[2], base = base),
    vip = new("VipTicket", event = p[2], base = base),
    backstage = new("BackstageTicket", event = p[2], base = base))
  print(t)
  cat(sprintf("price: %.2f", price(t)), "\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