كتل init والتحقق من الصحة
جزء من قسم البرمجة كائنية التوجه في رحلة Kotlin على Coddy. الدرس 4 من 57.
يتم تشغيل كتلة init عند إنشاء نسخة، مباشرةً بعد تعيين معاملات المُنشئ. وهي المكان المخصص لشفرة الإعداد التي لا تلائم تصريح خاصية واحدًا:
class Order(val id: Int, items: List<Int>) {
val total: Int
val count: Int
init {
total = items.sum()
count = items.size
println("created order $id")
}
}داخل main:
val o = Order(7, listOf(4, 6, 10))
println("${o.count} items, total ${o.total}")الناتج:
created order 7
3 items, total 20تتحقق require(condition) { message } من وسيطة وتطرح IllegalArgumentException مع الرسالة عندما تكون قيمتها خاطئة. ووضعها داخل init يعني أنه لا يمكن أبدًا إنشاء مثيل غير صالح:
class Percentage(val value: Int) {
init {
require(value in 0..100) { "percentage must be 0-100, was $value" }
}
}داخل main:
println(Percentage(42).value)
try {
Percentage(150)
} catch (e: IllegalArgumentException) {
println(e.message)
}الناتج:
42
percentage must be 0-100, was 150يمكن أن يحتوي الصنف على عدة كتل init؛ حيث تُنفَّذ بالترتيب، مع مهيئات الخصائص، من الأعلى إلى الأسفل:
class Demo(name: String) {
val first = "first: $name".also { println(it) }
init { println("init 1") }
val second = "second".also { println(it) }
init { println("init 2") }
}داخل main:
Demo("x")
println("done")الناتج:
first: x
init 1
second
init 2
doneيُبقي التحقّق في init القاعدة بجوار البيانات. ويمكن للكود الذي يتلقى مثيلًا أن يثق به دون التحقّق مرة أخرى:
class Email(val address: String) {
init {
require("@" in address) { "not an email: $address" }
}
}
fun send(to: Email) { /* لا حاجة للتحقق من العنوان مرة أخرى */ }التحدي
سهلأكمل الصنف Password. تتحقق كتلة init، باستخدام require، من أن النص يحتوي على 8 أحرف على الأقل (الرسالة too short) وأنه يتضمن رقمًا (الرسالة needs a digit)، بهذا الترتيب. تُحسب الخاصية strength في init: تكون strong عندما يحتوي النص أيضًا على حرف كبير، وإلا تكون ok.
ينشئ الكود المتوفر كائن Password لكل سطر إدخال ويطبع strength أو رسالة الخطأ.
ضع الكود في Password.kt. يحتوي Main.kt على كود الإدخال/الإخراج المتوفر، ولا يمكن تعديله.
جرّب بنفسك
fun main() {
// كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
val input = generateSequence(::readLine).toList()
for (line in input) {
try {
println(Password(line).strength)
} catch (e: IllegalArgumentException) {
println(e.message)
}
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الفئات والكائنات
العمل مع الملفاتتعريف الفئاتالمنشئات الأساسيةكتل init والتحقق من الصحةالمنشئات الثانويةمراجعة - بطاقة المكتبة4الوراثة
الأصناف المفتوحة والأصناف الفرعيةتجاوز الأعضاءsuper والمنشئاتالأصناف المجرّدةمراجعة - دليل الموظفينتدرّب بنفسك: Playground لـ Kotlin