Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

الطرق الافتراضية

جزء من قسم البرمجة كائنية التوجه في رحلة R على Coddy. الدرس 8 من 57.

عندما لا تتطابق أي طريقة مع الفئة، تبحث UseMethod() عن الطريقة الافتراضية، وهي name.default. وتُستخدم كخيار احتياطي لكل فئة لا يعرفها النوع العام:

describe <- function(x) UseMethod("describe")
describe.dog <- function(x) paste("a dog called", x$name)
describe.default <- function(x) "something I do not know"
rex <- structure(list(name = "Rex"), class = "dog")
car <- structure(list(), class = "car")
print(describe(rex))
print(describe(car))

الناتج:

[1] "a dog called Rex"
[1] "something I do not know"

من دون طريقة افتراضية، يؤدي استدعاء الدالة العامة على فئة غير معروفة إلى التوقف مع ظهور خطأ:

describe <- function(x) UseMethod("describe")
describe.dog <- function(x) paste("a dog called", x$name)
car <- structure(list(), class = "car")
describe(car)

المخرجات:

Error in UseMethod("describe") : 
  no applicable method for 'describe' applied to an object of class "car"
Calls: describe
Execution halted

تُجري القيم البسيطة عملية التوجيه أيضًا. فالعدد الذي لا يملك سمة فئة له الفئة الضمنية numeric، والنص له character، وTRUE له logical، لذا تعمل الأساليب التي تحمل هذه الأسماء على المتجهات العادية:

describe <- function(x) UseMethod("describe")
describe.numeric <- function(x) paste("numbers adding up to", sum(x))
describe.character <- function(x) paste("words:", paste(x, collapse = " "))
describe.default <- function(x) "something else"
print(describe(c(1, 2, 3)))
print(describe(c("a", "b")))
print(describe(TRUE))

الناتج:

[1] "numbers adding up to 6"
[1] "words: a b"
[1] "something else"

يمكن للطريقة الافتراضية أيضًا أن ترفض بأدب: باستخدام stop() مع رسالة تسمّي الفئة، حتى يعرف المستدعي ما الذي حدث خطأ. ‏class(x)[1] هي الفئة الأولى للكائن:

area <- function(shape) UseMethod("area")
area.square <- function(shape) shape$side^2
area.default <- function(shape) {
  stop("cannot compute the area of a ", class(shape)[1], call. = FALSE)
}
for (s in list(structure(list(side = 2), class = "square"), structure(list(), class = "blob"))) {
  cat(tryCatch(area(s), error = function(e) conditionMessage(e)), "\n")
}

الناتج:

4 
cannot compute the area of a blob 
challenge icon

التحدي

سهل

أكمل الدالة العامة describe(x) في Describe.R وطرائقها للمتجهات العادية:

  • تعيد describe.numeric() القيمة 3 numbers, sum 6.
  • تعيد describe.character() القيمة 2 words, longest: apple (أول كلمة من الكلمات الأطول عند التعادل).
  • تعيد describe.logical() القيمة 2 of 3 are TRUE.
  • تعيد describe.default() القيمة something else.

يقرأ الكود المرفق الأسطر num 1,2,3 أو chr apple,kiwi أو lgl TRUE,FALSE,TRUE أو أي كلمة أخرى مع قيم، ثم يحولها إلى قائمة. ويطبع describe() لكل منها.

ضع الكود الخاص بك في Describe.R. يحتوي main.R على كود الإدخال/الإخراج المرفق ولا يمكن تعديله.

جرّب بنفسك

source("Describe.R")

# كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  values <- strsplit(p[2], ",")[[1]]
  x <- switch(p[1],
    num = as.numeric(values),
    chr = values,
    lgl = as.logical(values),
    list(values))
  cat(describe(x), "\n", sep = "")
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم R عبر الإنترنت