تحديث الأساليب والحقول
جزء من قسم البرمجة كائنية التوجه في رحلة R على Coddy. الدرس 38 من 57.
توجد الأساليب في قائمة methods الخاصة بـ setRefClass(). داخل الأسلوب، تكون الحقول أسماءً عادية، ويغيّر <<- قيمة حقل. في مشغّل Coddy، تطبع R ملاحظةً حول الحزمة الاختيارية codetools عند تعريف فئة تحتوي على أساليب، لذا أحط التعريف داخل suppressMessages():
Counter <- suppressMessages(setRefClass("Counter",
fields = list(count = "numeric"),
methods = list(
add = function(n = 1) {
count <<- count + n
},
report = function() paste("count is", count)
)
))
c1 <- Counter$new(count = 0)
c1$add()
c1$add(5)
print(c1$report())الناتج:
[1] "count is 6".self هو الكائن الذي تم استدعاء الطريقة عليه. الطريقة التي تنتهي بـ invisible(.self) تُرجع الكائن، لذا يمكن تسلسل الاستدعاءات:
Counter <- suppressMessages(setRefClass("Counter",
fields = list(count = "numeric"),
methods = list(
add = function(n = 1) {
count <<- count + n
invisible(.self)
}
)
))
c1 <- Counter$new(count = 0)
c1$add(2)$add(3)$add(4)
print(c1$count)الناتج:
[1] 9تعمل الطريقة initialize داخل $new(). تعمل initFields(...) على تعيين الحقول التي تم تمريرها؛ وبعد ذلك يمكن للطريقة إعطاء قيم افتراضية للحقول الأخرى. تستدعي الطرق بعضها بعضًا بالاسم:
Account <- suppressMessages(setRefClass("Account",
fields = list(owner = "character", balance = "numeric"),
methods = list(
initialize = function(...) {
initFields(...)
if (length(balance) == 0) balance <<- 0
invisible(.self)
},
deposit = function(x) balance <<- balance + x,
deposit_twice = function(x) {
deposit(x)
deposit(x)
}
)
))
a <- Account$new(owner = "Ada")
a$deposit_twice(10)
print(a$balance)الناتج:
[1] 20داخل إحدى الطرق، يؤدي استخدام <- العادي مع اسم حقل إلى إنشاء متغير محلي بهذا الاسم، مع ترك الحقل دون تغيير. استخدم <<- عند كل تغيير لحقل:
Counter <- suppressMessages(setRefClass("Counter",
fields = list(count = "numeric"),
methods = list(
broken = function() count <- count + 1,
working = function() count <<- count + 1
)
))
c1 <- Counter$new(count = 0)
c1$broken()
c1$broken()
c1$working()
print(c1$count)الناتج:
[1] 1التحدي
سهلأكمل الفئة المرجعية Stack في Stack.R. تحتفظ بعناصرها في الحقل items (من النوع character، والعنصر الأعلى في النهاية) ولها أربع طرائق:
- تضيف
push(x)القيمةxإلى الأعلى وتُرجعinvisible(.self)، بحيث يمكن تسلسل عمليات الإضافة؛ - تزيل
pop()العنصر الأعلى وتُرجعه، أو تُرجعnothingعندما تكون المكدسة فارغة؛ - تُرجع
peek()العنصر الأعلى دون إزالته، أوnothing؛ - تُرجع
size()عدد العناصر.
التعريف مغلف بالفعل داخل suppressMessages(). يقرأ الكود المُزوَّد الأوامر push a b وpop وpeek، ثم يضيف عنصرين آخرين باستدعاء واحد متسلسل ويطبع الحجم.
ضع الكود في Stack.R. يحتوي main.R على كود الإدخال/الإخراج المُزوَّد ولا يمكن تعديله.
جرّب بنفسك
source("Stack.R")
# كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
input <- suppressWarnings(readLines(file("stdin")))
s <- Stack$new()
for (cmd in input) {
if (startsWith(cmd, "push ")) {
items <- strsplit(substring(cmd, 6), " ")[[1]]
for (it in items) s$push(it)
} else if (cmd == "pop") {
cat("popped ", s$pop(), "\n", sep = "")
} else if (cmd == "peek") {
cat("top ", s$peek(), "\n", sep = "")
}
}
s$push("x")$push("y")
cat("size after two chained pushes: ", s$size(), "\n", sep = "")
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات S3
التعامل مع الملفاتالقوائم باستخدام فئةدوال المُنشئأساليب الطباعة والتنسيقأدوات التحقق والمساعدةمراجعة - درجات الحرارة2S3 الدوال العامة والطرق
الدوال العامة وUseMethodالطرق الافتراضيةطرق الدوال العامة الأساسيةأساسيات NextMethodمراجعة - مساحات الأشكال8الأصناف المرجعية
تعريف الأصناف المرجعيةتحديث الأساليب والحقولدلالات النسخالوراثة وcallSuperمراجعة - قائمة المهامتدرّب بنفسك: مترجم R عبر الإنترنت