متجهات الأصناف
جزء من قسم البرمجة كائنية التوجه في رحلة 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 عبر الإنترنت