تنظيم الكود وإعادة استخدامه بفعالية
لقد قطعنا شوطاً طويلاً في رحلتنا لتعلم البرمجة بلغة الجافا! بعد أن أتقنتَ بناء البرامج التي تتخذ القرارات (جمل الشرط) وتُكرر المهام (الحلقات)، حان الوقت للانتقال إلى مفهوم أساسي لا يقل أهمية: **الدوال (Methods)**. الدوال هي اللبنة التي ستمكنك من كتابة كود منظم، قابل لإعادة الاستخدام، وسهل الصيانة.
في هذه الوحدة، سنتعلم كيف نقوم بتجميع أجزاء من الكود في كتل منطقية قابلة للاستدعاء، وكيف تمرير البيانات إليها، وكيف يمكنها أن ترجع لنا نتائج. هذا المفهوم حيوي لأي مبرمج محترف.
بنهاية هذه الوحدة، ستكون قادرًا على:
void Methods).return لإرجاع القيم من الدوال.الدالة (Method)، والتي يطلق عليها أحيانًا "وظيفة" أو "روتين" في لغات برمجة أخرى، هي عبارة عن **كتلة منظمة من التعليمات البرمجية تؤدي مهمة محددة**. تخيلها كـ "صندوق أسود" يأخذ مدخلات معينة، يُجري عليها بعض العمليات، وربما يُنتج مخرجات (نتائج).
المدخلات التي تستقبلها الدالة تسمى **باراميترات (Parameters)**، والنتيجة التي تُعيدها تسمى **قيمة مرجعة (Return Value)**. هذه الأوامر لا تُنفّذ إلا إذا قمنا بـ **استدعاء (Calling)** الدالة بالاسم الذي عرفناها به.
لغة جافا، مثلها مثل معظم لغات البرمجة، تحتوي على الكثير من الدوال الجاهزة (Built-in Methods) التي يمكن استخدامها مباشرةً دون الحاجة لتعريفها. هذه الدوال هي جزء من المكتبات القياسية للغة، وتوفر وظائف شائعة. على سبيل المثال، دوال الطباعة التي استخدمناها سابقًا هي في الحقيقة دوال جاهزة:
// دالة print() تطبع النص بدون إضافة سطر جديد بعده
System.out.print("هذا نص سيتم طباعته على نفس السطر.");
// دالة println() تطبع النص ثم تنتقل إلى سطر جديد
System.out.println("هذا نص آخر مع سطر جديد بعده.");
// دالة printf() تطبع النص مع تنسيقات محددة (مثل الأرقام والنصوص)
// %d لتنسيق الأعداد الصحيحة، %s لتنسيق النصوص، %n لسطر جديد
System.out.printf("الرقم: %d، النص: %s%n", 123, "مثال على printf");
هذه الدوال هي جزء من كائنات (Objects) مثل System.out. ستفهم هذا المفهوم بشكل أعمق بكثير في الوحدات المتقدمة حول البرمجة الكائنية (Object-Oriented Programming).
عند تعريف أي دالة جديدة في جافا، نستخدم بنية محددة تخبر المترجم (Compiler) عن كيفية عمل هذه الدالة وما تتوقعه من مدخلات وماذا تُرجع كمخرج. فهم هذه البنية أمر بالغ الأهمية.
البنية العامة لتعريف الدالة (Method Signature):
modifier returnType methodName(Parameter List) {
// جسم الدالة (Method Body) - الأوامر التي تنفذها الدالة
// ...
// [return value;] // جملة اختيارية إذا كانت الدالة ترجع قيمة
}
modifier (المعدّل):** يحدد طريقة الوصول إلى الدالة (من أين يمكن استدعاؤها) وخصائصها الأخرى. أمثلة شائعة:
public: هذا المعدّل يعني أن الدالة يمكن الوصول إليها (استدعاؤها) من أي كلاس آخر في برنامجك.private: يعني أن الدالة يمكن الوصول إليها فقط من داخل نفس الكلاس الذي عُرفت فيه. (مفهوم متقدم سنتناوله في OOP).static: هذه الكلمة المحجوزة تجعل الدالة مرتبطة بـ **الكلاس نفسه** وليس بكائن معين من الكلاس. لهذا السبب نستخدمها دائمًا مع دالة `main` حاليًا، ولتتمكن الدوال الأخرى التي نعرفها من أن تُستدعى مباشرةً من `main` دون الحاجة لإنشاء كائن. سنتعرف عليه بتفصيل أكبر عند دراسة البرمجة الكائنية (OOP).returnType (نوع القيمة المرجعة):** يحدد نوع البيانات الذي سترجعه الدالة بعد اكتمال تنفيذها. يمكن أن يكون أي نوع بيانات صالح في جافا (مثل: int، double، String، boolean، أو حتى كائن من كلاس معين).
void:** إذا لم تُرجع الدالة أي قيمة على الإطلاق (أي أن وظيفتها هي مجرد تنفيذ أوامر مثل الطباعة أو تغيير حالة شيء ما دون إعطاء نتيجة مباشرة)، نكتب الكلمة المحجوزة void كنوع إرجاع.methodName (اسم الدالة):** هو الاسم الذي تستخدمه لاستدعاء الدالة في كودك. يجب أن يكون اسمًا معبرًا (Descriptive) عن وظيفة الدالة بحيث يسهل فهم ما تفعله (مثال: `calculateSum` لحساب المجموع، `printReport` لطباعة تقرير، `getUserInput` للحصول على إدخال المستخدم). يفضل أن تبدأ أسماء الدوال بحرف صغير وتتبع نمط "camelCase" (مثال: `myNewMethod`).Parameter List (قائمة الباراميترات):** هي المدخلات أو القيم التي تستقبلها الدالة عند استدعائها. تحدد أنواع وعدد المتغيرات التي تحتاجها الدالة لأداء وظيفتها.
int age, String name).().{}.void)دالة وظيفتها فقط طباعة رسالة ترحيب بسيطة، ولا تحتاج لإرجاع أي قيمة، لذا يكون نوع الإرجاع void.
public class SimpleMethodExample {
// تعريف دالة اسمها welcomeMessage
// المعدّل: public static (مطلوب حالياً للاستدعاء من دالة main)
// نوع الإرجاع: void (لا ترجع قيمة)
// قائمة الباراميترات: () فارغة (لا تستقبل مدخلات)
public static void welcomeMessage() {
System.out.println("Welcome to Java Programming!");
}
public static void main(String[] args) {
// استدعاء الدالة welcomeMessage()
welcomeMessage();
System.out.println("مرحباً بك في الوحدة التاسعة!");
}
}
🔹 عند التنفيذ سيكون الناتج:
Welcome to Java Programming!
مرحباً بك في الوحدة التاسعة!
تذكر أن دالة main هي نقطة البداية لتنفيذ أي برنامج جافا. من داخلها، يمكننا استدعاء الدوال الأخرى التي نقوم بتعريفها.
int)دالة وظيفتها جمع عددين صحيحين وإرجاع ناتج الجمع. بما أنها تُعيد قيمة عدد صحيح، سيكون نوع الإرجاع int.
public class SumMethodExample {
// تعريف دالة اسمها sum
// المعدّل: public static
// نوع الإرجاع: int (ترجع عددًا صحيحًا)
// قائمة الباراميترات: (int a, int b) تستقبل عددين صحيحين
public static int sum(int a, int b) {
int result = a + b; // تقوم بجمع العددين
return result; // إرجاع النتيجة
}
public static void main(String[] args) {
// استدعاء الدالة sum() مع تمرير القيم 10 و 5
// وتخزين القيمة المرجعة في المتغير 'total'
int total = sum(10, 5);
System.out.println("10 + 5 = " + total); // طباعة النتيجة المخزنة
// يمكن أيضاً استخدام القيمة المرجعة مباشرةً في تعبير الطباعة
System.out.println("20 + 7 = " + sum(20, 7));
}
}
🔹 عند التنفيذ سيكون الناتج:
10 + 5 = 15
20 + 7 = 27
Stringدالة تستقبل اسم شخص كنص (String) وتطبع رسالة ترحيب مخصصة له. بما أنها لا ترجع قيمة، نوع الإرجاع هو void.
public class GreetMethodExample {
// تعريف دالة اسمها greet
// نوع الإرجاع: void (لا ترجع قيمة)
// قائمة الباراميترات: (String name) تستقبل نصًا (اسم)
public static void greet(String name) {
System.out.println("Hello " + name + ", welcome to Java!");
}
public static void main(String[] args) {
// استدعاء الدالة greet() بأسماء مختلفة لتمريرها كـ parameters
greet("Ahmed");
greet("Sara");
greet("Student");
}
}
🔹 عند التنفيذ سيكون الناتج:
Hello Ahmed, welcome to Java!
Hello Sara, welcome to Java!
Hello Student, welcome to Java!
doubleدالة لتحويل درجة الحرارة من مقياس فهرنهايت إلى مقياس مئوي. بما أن درجة الحرارة يمكن أن تكون كسرية، فإن نوع الإرجاع سيكون double.
public class TemperatureConverter {
// تعريف دالة اسمها toCelsius
// نوع الإرجاع: double (ترجع رقمًا عشريًا مزدوج الدقة)
// قائمة الباراميترات: (double fahrenheit) تستقبل درجة حرارة بالفهرنهايت
public static double toCelsius(double fahrenheit) {
// صيغة التحويل من فهرنهايت إلى مئوية
double celsius = (fahrenheit - 32) * 5 / 9;
return celsius;
}
public static void main(String[] args) {
// استدعاء الدالة toCelsius() وتخزين القيمة المرجعة
double tempFahrenheit = 98.6;
double tempCelsius = toCelsius(tempFahrenheit);
System.out.println("Temperature " + tempFahrenheit + " Fahrenheit in Celsius: " + tempCelsius);
// مثال آخر مباشرة دون تخزين في متغير
System.out.println("Temperature 32.0 Fahrenheit in Celsius: " + toCelsius(32.0)); // درجة تجمد الماء
}
}
🔹 عند التنفيذ سيكون الناتج:
Temperature 98.6 Fahrenheit in Celsius: 37.0
Temperature 32.0 Fahrenheit in Celsius: 0.0
القيمة المرجعة هي **النتيجة التي تُعيدها الدالة إلى الجزء الذي استدعاها** بعد اكتمال تنفيذها. عندما تحدد نوع قيمة مرجعة غير void لدالتك (مثل int، String، double، إلخ)، فهذا يعني أن الدالة ستقوم بحساب قيمة معينة أو جلبها، ثم تُعيدها لتكون متاحة للاستخدام في مكان الاستدعاء.
جملة return هي الكلمة المحجوزة التي تُستخدم لإرجاع القيمة من الدالة. يجب أن يتوافق نوع القيمة المُرجعة مع returnType المحدد في تعريف الدالة. بمجرد أن يصل تنفيذ الدالة إلى جملة `return`، تتوقف الدالة عن العمل وتعيد القيمة المحددة.
عند استدعاء دالة ترجع قيمة، يمكننا التعامل مع القيمة المرجعة بعدة طرق:
public class ReturnValueExample {
public static int multiply(int num1, int num2) {
return num1 * num2;
}
public static void main(String[] args) {
int product = multiply(3, 4); // الدالة multiply سترجع 12
System.out.println("ناتج الضرب هو: " + product); // الناتج: ناتج الضرب هو: 12
}
}
public class ReturnValueDirectUse {
public static String getFullName(String firstName, String lastName) {
return firstName + " " + lastName;
}
public static void main(String[] args) {
// استخدام القيمة المرجعة مباشرة في الطباعة
System.out.println("الاسم الكامل: " + getFullName("محمد", "علي"));
// الناتج: الاسم الكامل: محمد علي
// استخدام القيمة المرجعة في شرط
if (getFullName("محمد", "علي").length() > 10) {
System.out.println("الاسم الكامل طويل.");
}
}
}
public class ReturnValueAsParameter {
public static int add(int x, int y) {
return x + y;
}
public static void printSum(int sum) {
System.out.println("المجموع هو: " + sum);
}
public static void main(String[] args) {
// ناتج add(5, 7) (وهو 12) يتم تمريره كباراميتر لدالة printSum
printSum(add(5, 7)); // الناتج: المجموع هو: 12
}
}
void:
إذا كان نوع الإرجاع للدالة هو void، فهذا يعني أنها لا ترجع أي قيمة على الإطلاق. وبالتالي، لا يمكنك:
return مع قيمة (فقط return; لإنهاء الدالة مبكرًا).لقد أكملتَ هذه الوحدة بفهم عميق لمفهوم **الدوال (Methods)** في Java، وهي لبنات بناء أساسية لبرامج منظمة وفعالة.
modifier returnType methodName(Parameter List) { ... }.void:** لا ترجع شيئًا، وتُستخدم فقط لتنفيذ مهمة معينة (مثل الطباعة أو تعديل حالة).int, double, String)، ويتم ذلك باستخدام كلمة return.الدوال هي العمود الفقري لأي برنامج جافا كبير ومعقد، وإتقانها سيفتح لك آفاقًا جديدة في تطوير البرمجيات. تذكر أن الممارسة هي المفتاح! في الوحدة القادمة، سنتعلم عن **المصفوفات (Arrays)**، وهي هياكل بيانات تسمح لنا بتخزين مجموعات من القيم من نفس النوع بكفاءة.
اختبر فهمك لمفهوم الدوال من خلال حل التمارين التالية. حاول كتابة الكود بنفسك قبل البحث عن الحلول!
اكتب دالة اسمها calculateSquare تستقبل عددًا صحيحًا واحدًا (int) كباراميتر، وترجع مربع هذا العدد (int). ثم استدعِ هذه الدالة من دالة main مع عدة أرقام مختلفة واطبع النتائج.
public class SquareCalculator {
// اكتب الدالة calculateSquare هنا
// مثال: public static int calculateSquare(int number) { ... }
public static void main(String[] args) {
// استدعِ الدالة calculateSquare واطبع النتائج
// مثال: System.out.println("مربع العدد 5 هو: " + calculateSquare(5));
}
}
اكتب دالة اسمها printGreeting تستقبل اسم شخص (String) وعمره (int) كباراميترين. لا ترجع هذه الدالة أي قيمة (void)، بل تقوم بطباعة رسالة ترحيب مخصصة على الشاشة، مثل:
مرحباً يا [الاسم]، عمرك هو [العمر] سنة.
استدعِ الدالة من main مع بيانات مختلفة.
public class CustomGreeting {
// اكتب الدالة printGreeting هنا
// مثال: public static void printGreeting(String name, int age) { ... }
public static void main(String[] args) {
// استدعِ الدالة printGreeting
// مثال: printGreeting("أحمد", 30);
}
}
اكتب دالة اسمها divideNumbers تستقبل رقمين عشريين (double) كباراميترين (المقسوم والمقسوم عليه)، وترجع ناتج قسمة الأول على الثاني (double).
تلميح: فكر في حالة القسمة على صفر وكيف يمكنك التعامل معها داخل الدالة (مثلاً، إرجاع قيمة خاصة مثل Double.NaN إذا كان المقسوم عليه صفرًا، أو طباعة رسالة خطأ. معالجة الاستثناءات ستكون موضوعًا في وحدات متقدمة).
public class DivisionCalculator {
// اكتب الدالة divideNumbers هنا
// مثال: public static double divideNumbers(double dividend, double divisor) { ... }
public static void main(String[] args) {
// استدعِ الدالة divideNumbers واطبع النتائج
// مثال: System.out.println("ناتج القسمة: " + divideNumbers(10.0, 2.0));
// مثال: System.out.println("ناتج القسمة على صفر: " + divideNumbers(5.0, 0.0));
}
}
صمم دالة اسمها calculateAverage تستقبل خمس درجات صحيحة (int grade1, int grade2, int grade3, int grade4, int grade5) كباراميترات، وتحسب المعدل العام لهذه الدرجات، ثم ترجع الناتج كقيمة عشرية (double).
استدعِ هذه الدالة من main واطبع المعدل.
public class GradeAverageCalculator {
// اكتب الدالة calculateAverage هنا
// مثال: public static double calculateAverage(int g1, int g2, int g3, int g4, int g5) { ... }
public static void main(String[] args) {
// استدعِ الدالة calculateAverage واطبع النتائج
// مثال: System.out.println("متوسط الدرجات هو: " + calculateAverage(85, 90, 78, 92, 88));
}
}