الأصناف الافتراضية
جزء من قسم البرمجة كائنية التوجه في رحلة R على Coddy. الدرس 34 من 57.
تصف الفئة الافتراضية ما تشترك فيه عائلة من الفئات، ولا يمكن أن تمتلك كائنات خاصة بها. صرّح عنها باستخدام representation("VIRTUAL")؛ وتستخدم فئاتها الفرعية contains كالمعتاد:
setClass("Shape", representation("VIRTUAL"))
setClass("Circle", contains = "Shape", slots = c(r = "numeric"))
setClass("Square", contains = "Shape", slots = c(side = "numeric"))
cat(isVirtualClass("Shape"), is(new("Circle", r = 1), "Shape"), "\n")
cat(tryCatch({ new("Shape"); "made" }, error = function(e) "not allowed"), "\n")الناتج:
TRUE TRUE
not allowed تعمل طريقة للفئة الافتراضية مع كل فئة فرعية. هنا تستدعي describe() الخاصة بـ Shape الدالة area()، التي تنفذها كل فئة فرعية، لذا تُكتب الوصف مرة واحدة:
setClass("Shape", representation("VIRTUAL"))
setClass("Circle", contains = "Shape", slots = c(r = "numeric"))
setClass("Square", contains = "Shape", slots = c(side = "numeric"))
invisible(setGeneric("area", function(s) standardGeneric("area")))
invisible(setGeneric("describe", function(s) standardGeneric("describe")))
setMethod("area", "Circle", function(s) pi * s@r^2)
setMethod("area", "Square", function(s) s@side^2)
setMethod("describe", "Shape", function(s) sprintf("%s with area %.2f", class(s), area(s)))
for (s in list(new("Circle", r = 1), new("Square", side = 2))) cat(describe(s), "\n")الناتج:
Circle with area 3.14
Square with area 4.00 يمكن لصنف افتراضي أن يعلن عن خانات، والتي يمتلكها كل صنف فرعي بعد ذلك:
setClass("Shape", representation("VIRTUAL", label = "character"))
setClass("Square", contains = "Shape", slots = c(side = "numeric"))
sq <- new("Square", label = "tile", side = 2)
print(slotNames("Square"))الناتج:
[1] "side" "label"setClassUnion() ينشئ فئة افتراضية من الفئات الموجودة. تقبل خانة من هذا النوع أيًّا منها، مثل جهة اتصال تكون إما عنوان بريد إلكتروني أو رقم هاتف:
setClassUnion("Contact", c("character", "numeric"))
setClass("Friend", slots = c(name = "character", contact = "Contact"))
a <- new("Friend", name = "Ada", contact = "ada@x.org")
b <- new("Friend", name = "Bo", contact = 5550123)
cat(class(a@contact), class(b@contact), "\n")
cat(tryCatch({ new("Friend", name = "Cy", contact = TRUE); "ok" }, error = function(e) "refused"), "\n")الناتج:
character numeric
refused التحدي
سهلتشترك المدفوعات في الفئة الافتراضية Payment (الخانة amount) والدالتين العامتين fee() وreceipt()، وجميعها موجودة في Payment.R. أكمل ما يلي:
- في
Payment.R، طريقةreceipt()للفئةPayment:card: 100.00 + 2.00 fee، بحيث تُبنى من اسم الفئة بأحرف صغيرة، وamountوfee()؛ - في
Card.R، الفئةCard(التي تحتوي علىPayment) وطريقةfee()الخاصة بها: 2% من المبلغ؛ - في
Cash.R، الفئةCashوطريقةfee()الخاصة بها: 0.
يقرأ الكود المزوَّد الأسطر card 100 أو cash 20، ويطبع إيصال كل دفعة وإجمالي المبلغ المفروض، ثم يتحقق من أن Payment افتراضية ولا يمكن إنشاؤها.
ضع الكود الخاص بك في Payment.R وCard.R وCash.R. يحتوي main.R على كود الإدخال/الإخراج المزوَّد، ولا يمكن تعديله.
جرّب بنفسك
source("Payment.R")
source("Card.R")
source("Cash.R")
# كود الإدخال/الإخراج المُزوَّد: اتركه كما هو
input <- suppressWarnings(readLines(file("stdin")))
total <- 0
for (line in input) {
p <- strsplit(line, " ")[[1]]
amount <- as.numeric(p[2])
pay <- switch(p[1], card = new("Card", amount = amount), cash = new("Cash", amount = amount))
cat(receipt(pay), "\n", sep = "")
total <- total + amount + fee(pay)
}
cat(sprintf("charged: %.2f", total), "\n", sep = "")
cat("Payment is virtual: ", isVirtualClass("Payment"), "\n", sep = "")
cat(tryCatch({ new("Payment", amount = 1); "created a Payment" }, error = function(e) "cannot create a Payment"), "\n", sep = "")
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات S3
التعامل مع الملفاتالقوائم باستخدام فئةدوال المُنشئأساليب الطباعة والتنسيقأدوات التحقق والمساعدةمراجعة - درجات الحرارة7S4 الوراثة
التوسعة باستخدام containscallNextMethodالأصناف الافتراضيةالتحقق من الأنواع باستخدام is()مراجعة - حارس حديقة الحيوانات2S3 الدوال العامة والطرق
الدوال العامة وUseMethodالطرق الافتراضيةطرق الدوال العامة الأساسيةأساسيات NextMethodمراجعة - مساحات الأشكالتدرّب بنفسك: مترجم R عبر الإنترنت