Menu
CoddyTech

متجهات الأصناف

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

يأتي التوريث في S3 من متجه الفئات. الكائن الذي له class = c("manager", "employee") هو مدير وموظف أيضًا. عندما لا يكون للتابع العام طريقة لـ manager، ينتقل التوجيه ويستخدم طريقة employee:

pay <- function(x) UseMethod("pay")
pay.employee <- function(x) x$salary / 12
m <- structure(list(name = "Ada", salary = 60000), class = c("manager", "employee"))
print(class(m))
print(pay(m))

المخرجات:

[1] "manager"  "employee"
[1] 5000

إن كتابة متجه الصنف يدويًا في كل مُنشئ تكرر تفاصيل الصنف الأب. بدلًا من ذلك، يأخذ مُنشئ الصنف الأب وسيطًا class ويضعه في مقدمة صنفه، ويستدعي مُنشئ الصنف الابن مُنشئ الصنف الأب:

new_employee <- function(name, salary, ..., class = character()) {
  structure(list(name = name, salary = salary, ...), class = c(class, "employee"))
}
new_manager <- function(name, salary, reports) {
  new_employee(name, salary, reports = reports, class = "manager")
}
m <- new_manager("Ada", 60000, 4)
print(class(m))
print(names(m))

المخرجات:

[1] "manager"  "employee"
[1] "name"    "salary"  "reports"

تجمع ... في مُنشئ الصنف الأب الحقول الإضافية للابن، وهي هنا reports، وتضعها بعد حقول الأب نفسه. لا يحتوي الموظف العادي على الحقل reports إطلاقًا:

new_employee <- function(name, salary, ..., class = character()) {
  structure(list(name = name, salary = salary, ...), class = c(class, "employee"))
}
e <- new_employee("Bo", 40000)
print(class(e))
print(names(e))

الناتج:

[1] "employee"
[1] "name"   "salary"

ترتيب متجه الفئات مهم: تأتي الفئة الأكثر تحديدًا أولًا. عندما تأتي الفئة الأصلية أولًا، تكون الأولوية لأساليبها ولا تُستخدم أساليب الفئة الفرعية أبدًا:

title <- function(x) UseMethod("title")
title.employee <- function(x) "employee"
title.manager <- function(x) "manager"
right <- structure(list(), class = c("manager", "employee"))
wrong <- structure(list(), class = c("employee", "manager"))
print(title(right))
print(title(wrong))

الناتج:

[1] "manager"
[1] "employee"
challenge icon

التحدي

سهل

يُوزَّع الموظفون والمديرون على ملفين. أكمل new_employee(name, salary, ..., class = character()) في Employee.R: تُرجع قائمة تحتوي على name وsalary وأي حقول إضافية من ...، مع متجه الفئات c(class, "employee"). ثم أكمل new_manager(name, salary, reports) في Manager.R، والتي تستدعي new_employee() مع الحقل الإضافي reports والفئة manager.

الدالة label() وطريقتها employee معطاتان، لذا يحصل المديرون على تسمية من دون طريقة خاصة بهم. يقرأ الكود المقدَّم أسطرًا بصيغة employee Bo 40000 أو manager Ada 60000 4 ويطبع متجه الفئات وأسماء الحقول والتسمية.

ضع كودك في Employee.R وManager.R. يحتوي main.R على كود الإدخال/الإخراج المقدَّم ولا يمكن تعديله.

جرّب بنفسك

source("Employee.R")
source("Manager.R")

# شيفرة الإدخال والإخراج المقدَّمة: اتركها كما هي
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  x <- if (p[1] == "manager") new_manager(p[2], as.numeric(p[3]), as.numeric(p[4])) else new_employee(p[2], as.numeric(p[3]))
  cat("class: ", paste(class(x), collapse = ", "), "\n", sep = "")
  cat("fields: ", paste(names(x), collapse = ", "), "\n", sep = "")
  cat(label(x), "\n", sep = "")
}
quiz iconاختبر نفسك

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

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

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