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

التوسعة باستخدام contains

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

contains = "Animal" يجعل فئة S4 جديدة فئةً فرعية من Animal. تحتوي الفئة الفرعية على كل خانة من خانات الفئة الأصلية بالإضافة إلى خاناتها الخاصة، وتأخذ new() جميع هذه الخانات:

setClass("Animal", slots = c(name = "character", age = "numeric"))
setClass("Dog", contains = "Animal", slots = c(breed = "character"))
rex <- new("Dog", name = "Rex", age = 3, breed = "collie")
print(slotNames("Dog"))
cat(rex@name, rex@breed)

الناتج:

[1] "breed" "name"  "age"  
Rex collie

الأساليب المكتوبة للصنف الأب تعمل مع الصنف الابن أيضًا. عندما لا يكون للنوع العام أسلوب لـ Dog، يستخدم S4 الأسلوب الخاص بـ Animal:

setClass("Animal", slots = c(name = "character"))
setClass("Dog", contains = "Animal")
invisible(setGeneric("intro", function(a) standardGeneric("intro")))
setMethod("intro", "Animal", function(a) paste("I am", a@name))
print(intro(new("Dog", name = "Rex")))

الناتج:

[1] "I am Rex"

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

setClass("Animal", slots = c(name = "character"))
setClass("Dog", contains = "Animal")
setClass("Cat", contains = "Animal")
invisible(setGeneric("sound", function(a) standardGeneric("sound")))
setMethod("sound", "Animal", function(a) "...")
setMethod("sound", "Dog", function(a) "woof")
cat(sound(new("Dog", name = "Rex")), sound(new("Cat", name = "Tom")))

الناتج:

woof ...

is(x, "Animal") تكون TRUE للكلب، والفتحة المُعلنة كـ "Animal" تقبل كائنًا من نوع Dog. تعمل الشيفرة المكتوبة للفئة الأب مع كل فئة فرعية:

setClass("Animal", slots = c(name = "character"))
setClass("Dog", contains = "Animal")
setClass("Owner", slots = c(pet = "Animal"))
rex <- new("Dog", name = "Rex")
o <- new("Owner", pet = rex)
cat(is(rex, "Animal"), is(o@pet, "Dog"))

الناتج:

TRUE TRUE
challenge icon

التحدي

سهل

الموظفون والمديرون هم فئات S4 في ملفين. يعلن Employee.R عن Employee (الفتحتان name وsalary) وعن العام describe()، ويحتاج إلى أسلوب لـ Employee يُرجع Bo earns 40000. في Manager.R أعلن عن Manager، الذي يتضمن Employee ويضيف الفتحة reports (من النوع numeric)، وتجاوز describe() بحيث يُرجع Ada earns 60000 and manages 4.

يقرأ الكود الم provided الأسطر employee Bo 40000 أو manager Ada 60000 4 ويطبع describe()، وما إذا كان الكائن موظفًا، وفتحه.

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

جرّب بنفسك

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", name = p[2], salary = as.numeric(p[3]), reports = as.numeric(p[4]))
  } else {
    new("Employee", name = p[2], salary = as.numeric(p[3]))
  }
  cat(describe(x), "\n", sep = "")
  cat("is an employee: ", is(x, "Employee"), ", slots: ", paste(slotNames(x), collapse = ", "), "\n", sep = "")
}
quiz iconاختبر نفسك

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

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

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