الدوال العامة وUseMethod
جزء من قسم البرمجة كائنية التوجه في رحلة R على Coddy. الدرس 7 من 57.
الدالة العامة هي دالة يكون جسمها هو UseMethod("name"). عند استدعائها، تنظر إلى فئة وسيطها الأول وتستدعي الطريقة name.class. تعمل print() وformat() بهذه الطريقة؛ ويمكنك كتابة دوال عامة خاصة بك أيضًا:
speak <- function(x) UseMethod("speak")
speak.dog <- function(x) paste(x$name, "says woof")
speak.cat <- function(x) paste(x$name, "says meow")
rex <- structure(list(name = "Rex"), class = "dog")
tom <- structure(list(name = "Tom"), class = "cat")
print(speak(rex))
print(speak(tom))المخرجات:
[1] "Rex says woof"
[1] "Tom says meow"يكتب المستدعي استدعاءً واحدًا، ويجيب كل كائن بطريقته الخاصة. هذا هو تعدد الأشكال: لا تحتاج الشفرة التي تكرّر على قائمة مختلطة إلى if لكل فئة:
speak <- function(x) UseMethod("speak")
speak.dog <- function(x) paste(x$name, "says woof")
speak.cat <- function(x) paste(x$name, "says meow")
pets <- list(structure(list(name = "Rex"), class = "dog"),
structure(list(name = "Tom"), class = "cat"),
structure(list(name = "Bo"), class = "dog"))
for (p in pets) cat(speak(p), "\n")الناتج:
Rex says woof
Tom says meow
Bo says woof تأخذ الطريقة معاملات الدالة العامة. امنح الدالة العامة معاملًا ... حتى تتمكن الطرق من قبول معاملات إضافية خاصة بها، مثل digits للدائرة:
area <- function(shape, ...) UseMethod("area")
area.square <- function(shape, ...) shape$side^2
area.circle <- function(shape, digits = 2, ...) round(pi * shape$r^2, digits)
sq <- structure(list(side = 3), class = "square")
ci <- structure(list(r = 1), class = "circle")
print(area(sq))
print(area(ci))
print(area(ci, digits = 4))الناتج:
[1] 9
[1] 3.14
[1] 3.1416UseMethod() يمرّر الاستدعاء إلى الطريقة ولا يعود أبدًا: أيًّا كانت القيمة التي تُرجعها الطريقة فهي نتيجة الدالة العامة، ولا يُنفَّذ الكود الذي يأتي بعد UseMethod(). لذلك تكون الدالة العامة سطرًا واحدًا:
size <- function(x) {
UseMethod("size")
cat("this line never runs\n")
}
size.box <- function(x) x$w * x$h
b <- structure(list(w = 2, h = 5), class = "box")
print(size(b))الناتج:
[1] 10التحدي
سهليتم تقسيم الأشكال على ثلاثة ملفات. أكمل الدالة العامة area() في Shape.R، ثم أضف الطريقتين area.circle() (باي مضروبًا في نصف القطر تربيعًا) في Circle.R وarea.rectangle() (العرض مضروبًا في الارتفاع) في Rectangle.R. البناة معطاة.
يقرأ الكود المزوّد الأسطر circle 2 أو rectangle 3 4 ويطبع فئة كل شكل ومساحته مع منزلتين عشريتين: circle: 12.57.
يجب أن تضع كودك في Shape.R وCircle.R وRectangle.R. يحتوي main.R على كود الإدخال/الإخراج المزوّد، ولا يمكن تعديله.
جرّب بنفسك
source("Shape.R")
source("Circle.R")
source("Rectangle.R")
# كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
s <- if (p[1] == "circle") new_circle(as.numeric(p[2])) else new_rectangle(as.numeric(p[2]), as.numeric(p[3]))
cat(sprintf("%s: %.2f", class(s), area(s)), "\n", sep = "")
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات S3
التعامل مع الملفاتالقوائم باستخدام فئةدوال المُنشئأساليب الطباعة والتنسيقأدوات التحقق والمساعدةمراجعة - درجات الحرارة2S3 الدوال العامة والطرق
الدوال العامة وUseMethodالطرق الافتراضيةطرق الدوال العامة الأساسيةأساسيات NextMethodمراجعة - مساحات الأشكالتدرّب بنفسك: مترجم R عبر الإنترنت