callNextMethod
جزء من قسم البرمجة كائنية التوجه في رحلة R على Coddy. الدرس 33 من 57.
داخل طريقة S4، تستدعي callNextMethod() طريقة الفئة الأصلية باستخدام الوسائط نفسها وتُرجع نتيجتها. تبني طريقة الفئة الابنة على إجابة الفئة الأصلية بدلًا من تكرارها:
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)))الناتج:
[1] "Ada earns 60000 and manages 4"ينطبق الأمر نفسه على show() أيضًا: يطبع الابن أسطر الوالد ثم أسطره الخاصة:
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)الناتج:
Employee: Ada
Reports: 4 تستدعي new() الدالة العامة initialize(). ويمكن لطريقة مخصّصة لها أن تملأ الخانات التي يتم تحديدها استنادًا إلى خانات أخرى. وهي تستدعي callNextMethod(.Object, ...) أولًا، ولذلك يظل الإعداد العادي وفحص الصلاحية قائمين:
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)الناتج:
[1] 7.5مثل NextMethod() في S3، تتسلسل callNextMethod() عبر عدة مستويات، حيث يضيف كل صنف الجزء الخاص به:
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)))الناتج:
30 60 110التحدي
سهلتأتي التذاكر في ثلاثة مستويات، وكل مستوى منها في ملفه الخاص. تم التصريح بالفئات والدالة العامة price(). أضف الأساليب:
Ticket.R: تُساويprice()السعر الأساسي؛ وتطبعshow()العبارةTicket for galaوسطرًا جديدًا.Vip.R: تُساويprice()1.5 من سعر التذكرة؛ وتطبعshow()سطر التذكرة ثمVIP lounge access.Backstage.R: تُساويprice()سعر VIP مضافًا إليه 50؛ وتطبعshow()أسطر VIP ثمBackstage pass.
استخدم callNextMethod() في أساليب الفئات الفرعية. يقرأ الكود المُقدَّم الأسطر vip gala 80 (المستوى، والفعالية، والسعر الأساسي) ويطبع كل تذكرة وسعرها.
ضع الكود في Ticket.R وVip.R وBackstage.R. يحتوي main.R على كود الإدخال/الإخراج المُقدَّم، ولا يمكن تعديله.
جرّب بنفسك
source("Ticket.R")
source("Vip.R")
source("Backstage.R")
# كود الإدخال/الإخراج المُزوَّد: اتركه كما هو
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 = "")
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات S3
التعامل مع الملفاتالقوائم باستخدام فئةدوال المُنشئأساليب الطباعة والتنسيقأدوات التحقق والمساعدةمراجعة - درجات الحرارة2S3 الدوال العامة والطرق
الدوال العامة وUseMethodالطرق الافتراضيةطرق الدوال العامة الأساسيةأساسيات NextMethodمراجعة - مساحات الأشكالتدرّب بنفسك: مترجم R عبر الإنترنت