الثوابت (static final)
جزء من قسم Object Oriented Programming في رحلة Java على Coddy — الدرس 18 من 87.
يؤدي دمج static و final إلى إنشاء ثابت - وهي قيمة تنتمي إلى الفئة ولا يمكن تغييرها أبداً. هذه هي الطريقة القياسية لتعريف الثوابت في Java.
public class GameSettings {
public static final int MAX_PLAYERS = 4;
public static final double GRAVITY = 9.81;
public static final String GAME_TITLE = "Space Adventure";
}حسب العرف، تستخدم أسماء الثوابت تنسيق UPPER_SNAKE_CASE لتمييزها عن المتغيرات العادية. وبما أنها static و final، فإنه يتم الوصول إليها من خلال اسم الفئة وقيمها مضمونة بأنها لن تتغير أبداً:
System.out.println(GameSettings.MAX_PLAYERS); // 4
// GameSettings.MAX_PLAYERS = 8; // خطأ! لا يمكن التعديلعادةً ما يتم التصريح عن الثوابت كـ public لأنها مخصصة للمشاركة عبر تطبيقك. فكر في قيم مثل Math.PI - فهو ثابت public static final يمكن لأي كود استخدامه.
لماذا نستخدم الثوابت بدلاً من القيم المكتوبة مباشرة (hardcoded)؟ إذا كتبت 4 في جميع أنحاء الكود الخاص بك واحتجت لاحقاً لتغييرها إلى 6، سيتعين عليك العثور على كل تكرار وتحديثه. باستخدام ثابت مثل MAX_PLAYERS، يمكنك تغييره في مكان واحد فقط.
تجعل الثوابت أيضًا الكود أكثر قابلية للقراءة - فالثابت MAX_PLAYERS أوضح من الرقم الغامض 4.
التحدي
سهللنقم ببناء أداة MathConstants التي تخزن القيم الرياضية المهمة كثوابت، بالإضافة إلى CircleCalculator الذي يستخدم تلك الثوابت لإجراء العمليات الحسابية.
ستقوم بإنشاء ملفين لتنظيم الكود الخاص بك:
MathConstants.java: قم بإنشاء فئة (class) تحتوي على ثوابت رياضية باستخدام حقولpublic static final:PIبالقيمة3.14159E(عدد أويلر) بالقيمة2.71828GOLDEN_RATIOبالقيمة1.61803
UPPER_SNAKE_CASEلأسماء الثوابت!Main.java: استخدم ثوابتك لإجراء حسابات الدائرة. ستتلقى نصف القطر كمدخل وتطبع ثلاثة أسطر:- مساحة الدائرة:
Area: [value] - محيط الدائرة:
Circumference: [value] - القطر مضروباً في النسبة الذهبية:
Golden Diameter: [value]
- مساحة الدائرة:
بالنسبة للحسابات:
- Area = PI * radius * radius
- Circumference = 2 * PI * radius
- Golden Diameter = 2 * radius * GOLDEN_RATIO
ستتلقى مدخلاً واحداً: نصف القطر (double).
قم بتنسيق جميع قيم المخرجات إلى منزلتين عشريتين باستخدام String.format("%.2f", value). قم بالوصول إلى ثوابتك من خلال اسم الفئة، مثل MathConstants.PI.
ورقة مرجعية
يؤدي الجمع بين static و final إلى إنشاء ثابت (constant) - وهي قيمة تنتمي إلى الفئة (class) ولا يمكن تغييرها أبداً:
public class GameSettings {
public static final int MAX_PLAYERS = 4;
public static final double GRAVITY = 9.81;
public static final String GAME_TITLE = "Space Adventure";
}حسب العرف البرمجي، تستخدم أسماء الثوابت نمط UPPER_SNAKE_CASE. يتم الوصول إلى الثوابت من خلال اسم الفئة:
System.out.println(GameSettings.MAX_PLAYERS); // 4
// GameSettings.MAX_PLAYERS = 8; // خطأ! لا يمكن التعديلعادةً ما يتم التصريح عن الثوابت كـ public لمشاركتها عبر تطبيقك. فهي تجعل الكود أكثر قابلية للصيانة والقراءة من خلال استبدال القيم المكتوبة مباشرة (hardcoded) بأسماء ذات معنى.
جرّب بنفسك
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double radius = scanner.nextDouble();
// TODO: احسب المساحة باستخدام MathConstants.PI
// الصيغة: PI * radius * radius
// TODO: احسب المحيط باستخدام MathConstants.PI
// الصيغة: 2 * PI * radius
// TODO: احسب القطر الذهبي باستخدام MathConstants.GOLDEN_RATIO
// الصيغة: 2 * radius * GOLDEN_RATIO
// TODO: اطبع النتائج منسقة إلى منزلتين عشريتين
// استخدم String.format("%.2f", value) للتنسيق
// تنسيق المخرجات:
// Area: [value]
// Circumference: [value]
// Golden Diameter: [value]
}
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
1أساسيات الـ OOP
الملفات الخارجيةمقدمة في الـ OOPالفئات (Classes) مقابل الكائنات (Objects)الكلمة المفتاحية thisالدوال (Methods)الحقول (Attributes)دالة البناء (Constructor)تعدد أشكال دالة البناء (Constructor Overloading)مراجعة - آلة حاسبة بسيطة4الوراثة
الوراثة الأساسية (extends)الكلمة المفتاحية superإعادة تعريف الدوال (@Override)تسلسل المنشئات (Constructor Chaining)كلاس Objectالوراثة الأحادية ومتعددة المستوياتلماذا لا توجد وراثة متعددة للكلاساتمراجعة - هيكلية الموظفين7الدوال الخاصة وفئة Object
دالة toString()equals() و hashCode()دالة clone()compareTo() و Comparableواجهة Comparatorمراجعة - الترتيب المخصص2محددات الوصول والتغليف
نظرة عامة على مستويات الوصولدوال Getter و Setterإخفاء البياناتالكلمة المفتاحية finalمراجعة - مدير الحساب البنكي5تعدد الأشكال (Polymorphism)
أساسيات الـ Method Overloadingالـ Method Overriding (في وقت التشغيل)الـ Upcasting والـ Downcastingمعامل الـ instanceofالفئات والدوال المجردة (Abstract)مراجعة - حاسبة الأشكال8مفاهيم OOP المتقدمة
الـ Composition مقابل الـ Inheritanceالـ Aggregation مقابل الـ Compositionالفئات الداخلية والمتداخلة والمجهولة (Inner, Nested & Anonymous)الـ Enums ودوالهاالـ Records (Java 16+)الـ Sealed Classes (Java 17+)11أنماط التصميم - الجزء الأول
مقدمة في أنماط التصميمنمط Singletonنمط Factoryنمط Builderنمط Observerنمط Strategy3خصائص الفئة والعضو الساكن
المتغيرات الخاصة بالكائن مقابل المتغيرات الساكنةالدوال الساكنةالكتل البرمجية الساكنةالثوابت (static final)ملخص - العداد والأدوات المساعدة6الواجهات (Interfaces) والأصناف المجردة (Abstract Classes)
مقدمة في الواجهات (Interfaces)تنفيذ الواجهات (Interfaces)تنفيذ واجهات متعددةالـ Default و Static في الواجهاتالأصناف المجردة مقابل الواجهاتالواجهات الوظيفية (Functional Interfaces)مراجعة - نظام الدفع9الأنواع العامة (Generics)
مقدمة في الأنواع العامةالأصناف العامة (Generic Classes)الدوال العامة (Generic Methods)معاملات الأنواع المقيدةالرموز البديلة (?, extends, super)مراجعة - الحاويات العامة12أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المكرر