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

ترتيب البحث عن الأساليب

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

في كل استدعاء، يستعرض R متجه الفئات من اليسار إلى اليمين ويشغّل أول طريقة يعثر عليها. إذا لم تكن لدى أي فئة طريقة، فإنه يستخدم الطريقة الافتراضية. يمكن للكائنات المختلفة في تسلسل هرمي واحد أن تتوقف عند مستويات مختلفة:

move <- function(x) UseMethod("move")
move.animal <- function(x) "walks"
move.bird <- function(x) "flies"
move.default <- function(x) "stays"
penguin <- structure(list(), class = c("penguin", "bird", "animal"))
dog <- structure(list(), class = c("dog", "animal"))
rock <- structure(list(), class = "rock")
cat(move(penguin), move(dog), move(rock))

الناتج:

flies walks stays

يتجاوز الطفل طريقةً في الأصل بإعادة تعريفها بطريقته الخاصة. يؤثر التجاوز في الطفل فقط وفي كل ما يندرج تحته؛ بينما يحتفظ الأصل وأطفاله الآخرون بطريقة الأصل:

move <- function(x) UseMethod("move")
move.animal <- function(x) "walks"
move.bird <- function(x) "flies"
move.penguin <- function(x) "swims"
penguin <- structure(list(), class = c("penguin", "bird", "animal"))
sparrow <- structure(list(), class = c("bird", "animal"))
cat(move(penguin), move(sparrow))

الناتج:

swims flies

يتم البحث عن كل generic بشكل مستقل. يمكن لكائن واحد أن يأخذ sound() من فئته الخاصة وmove() من فئة أب، ويمكن لطريقة الأب استدعاء generics أخرى تُجري التوزيع على الابن مرة أخرى:

sound <- function(x) UseMethod("sound")
move <- function(x) UseMethod("move")
describe <- function(x) UseMethod("describe")
sound.animal <- function(x) "..."
sound.dog <- function(x) "woof"
move.animal <- function(x) "walks"
describe.animal <- function(x) paste(x$name, "says", sound(x), "and", move(x))
rex <- structure(list(name = "Rex"), class = c("dog", "animal"))
print(describe(rex))

الناتج:

[1] "Rex says woof and walks"

بالنسبة إلى كائن له سمة فئة، ينظر التوزيع إلى تلك السمة فقط ثم إلى الافتراضي. لا يزال الكائن قائمةً من الداخل، لكن لا تتم تجربة طريقة لـ list:

size <- function(x) UseMethod("size")
size.list <- function(x) "a list"
size.default <- function(x) "default"
bag <- structure(list(1, 2), class = "bag")
cat(size(list(1, 2)), "/", size(bag))

الناتج:

a list / default
challenge icon

التحدي

سهل

المربع هو مستطيل ذو أضلاع متساوية. في Rectangle.R اكتب الدوال area.rectangle() وperimeter.rectangle() وname.rectangle()، والتي تُرجع rectangle 2x3. في Square.R أكمل new_square(side)، التي تستدعي new_rectangle() مع الفئة square، وتجاوز فقط name() باستخدام name.square()، والتي تُرجع square 2. يجب أن تستخدم المربعات الدالتين area() وperimeter() الخاصتين بالمستطيل.

الدوال العامة وnew_rectangle() مُعطاة. يقرأ الكود المُقدَّم أسطرًا تحتوي على رقمين (مستطيل) أو رقم واحد (مربع)، ويطبع square 2: area 4, perimeter 8.

يجب وضع الكود الخاص بك في Rectangle.R وSquare.R. يحتوي main.R على كود الإدخال/الإخراج المُقدَّم، ولا يمكن تعديله.

جرّب بنفسك

source("Rectangle.R")
source("Square.R")

# كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  n <- as.numeric(strsplit(line, " ")[[1]])
  s <- if (length(n) == 1) new_square(n[1]) else new_rectangle(n[1], n[2])
  cat(name(s), ": area ", area(s), ", perimeter ", perimeter(s), "\n", sep = "")
}
quiz iconاختبر نفسك

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

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

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