متجهات الأصناف
جزء من قسم البرمجة كائنية التوجه في رحلة 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"التحدي
سهليُوزَّع الموظفون والمديرون على ملفين. أكمل 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 = "")
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات S3
التعامل مع الملفاتالقوائم باستخدام فئةدوال المُنشئأساليب الطباعة والتنسيقأدوات التحقق والمساعدةمراجعة - درجات الحرارة2S3 الدوال العامة والطرق
الدوال العامة وUseMethodالطرق الافتراضيةطرق الدوال العامة الأساسيةأساسيات NextMethodمراجعة - مساحات الأشكالتدرّب بنفسك: مترجم R عبر الإنترنت