إنشاء الدوال العامة
جزء من قسم البرمجة كائنية التوجه في رحلة R على Coddy. الدرس 27 من 57.
يُنشأ عامّ S4 باستخدام setGeneric(). ويكون جسم الدالة standardGeneric("name")، وهو النظير في S4 لـ UseMethod(). تُعيد setGeneric() اسم العامّ، الذي يُطبع عند استدعائه في المستوى الأعلى:
setGeneric("area", function(shape) standardGeneric("area"))الناتج:
[1] "area"أحِط الاستدعاء بـ invisible() لإبقاء هذا السطر خارج المخرجات. ثم يضيف setMethod("area", "Circle", ...) الطريقة لإحدى الفئات:
setClass("Circle", slots = c(r = "numeric"))
setClass("Square", slots = c(side = "numeric"))
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
setMethod("area", "Square", function(shape) shape@side^2)
cat(area(new("Circle", r = 1)), area(new("Square", side = 3)))المخرجات:
3.141593 9للطريقة الوسيطات نفسها التي للدالة العامة. عندما تحتوي الدالة العامة على ...، يمكن للطريقة إضافة وسيطات مسماة خاصة بها بعدها:
setClass("Circle", slots = c(r = "numeric"))
invisible(setGeneric("describe", function(x, ...) standardGeneric("describe")))
setMethod("describe", "Circle", function(x, ..., digits = 2) {
paste("circle of area", round(pi * x@r^2, digits))
})
c1 <- new("Circle", r = 2)
print(describe(c1))
print(describe(c1, digits = 4))المخرجات:
[1] "circle of area 12.57"
[1] "circle of area 12.5664"تحتاج setMethod() إلى وجود الدالة العامة مسبقًا، لذا يُحمَّل الملف الذي يحتوي على setGeneric() أولًا. يؤدي استدعاء الفئة التي لا تملك طريقة إلى التوقف مع ظهور خطأ يذكر التوقيع:
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setClass("Circle", slots = c(r = "numeric"))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
area(42)المخرجات:
Error: unable to find an inherited method for function ‘area’ for signature ‘shape = "numeric"’
Execution haltedالتحدي
سهلالأشكال هي أصناف S4 موزعة على ثلاثة ملفات. في Shape.R أنشئ الدالتين العامتين area(shape) وperimeter(shape) باستخدام setGeneric()، وضعهما داخل invisible(). في Circle.R وSquare.R تُعرَّف الأصناف؛ أضف طريقتَي area وperimeter لكل صنف باستخدام setMethod().
يقرأ الكود المزوَّد الأسطر circle 2 أو square 3 ويطبع circle: area 12.57, perimeter 12.57.
ضع كودك في Shape.R وCircle.R وSquare.R. يحتوي main.R على كود الإدخال/الإخراج المزوَّد، ولا يمكن تعديله.
جرّب بنفسك
source("Shape.R")
source("Circle.R")
source("Square.R")
# كود الإدخال والإخراج المرفق: اتركه كما هو
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
s <- if (p[1] == "circle") new("Circle", r = as.numeric(p[2])) else new("Square", side = as.numeric(p[2]))
cat(sprintf("%s: area %.2f, perimeter %.2f", p[1], area(s), perimeter(s)), "\n", sep = "")
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات S3
التعامل مع الملفاتالقوائم باستخدام فئةدوال المُنشئأساليب الطباعة والتنسيقأدوات التحقق والمساعدةمراجعة - درجات الحرارة2S3 الدوال العامة والطرق
الدوال العامة وUseMethodالطرق الافتراضيةطرق الدوال العامة الأساسيةأساسيات NextMethodمراجعة - مساحات الأشكالتدرّب بنفسك: مترجم R عبر الإنترنت