جافا هي لغة برمجة حاسوبية للأغراض العامة، المتزامنة، المعتمدة على الصفوف، وغرضية التوجه
// يبدأ التعليق المكتوب على خط واحد ب .// /* يبدو التعليق المكتوب على عدة سطور بهذا الشكل. */ /** *تبدو التعليقات في ملفات لغة البرمجة جافا بهذا الشكل *و تستخدم لوصف الصف أو الصفات المختلفة لكائن معين. *:الصفات الرئيسية * *@author- اسم مؤلف الكود. *ويحتوي على معلومات الاتصال كالبريد الالكتروني لمؤلف الكود أو للمؤلفين. *@version- النسخة الحالية من البرنامج. *@since -الوقت الذي تم فيه إضافة هذا الجزء من البرنامج. *@param -من أجل وصف البارامترات المختلفة للمنهج (method). *@return -لوصف القيمة التي يرجعها المنهج. *@deprecated -لإظهار انتهاء صلاحية الكود أو عدم وجوب استخدامه. *@see - روابط إلى جزء آخر من المستندات */
استورد الصف ArrayList بدلاً من استيراد الرزمة java.util
كلّها
import java.util.ArrayList;
استورد جميع الصفوف الموجود داخل الرزمة
import java.security.*;
يحوي أي ملف جافا على صف عام، على المستوى الخارجي، له نفس اسم الملف
public class LearnJava {
ليعمل برنامج جافا يجب أن يحوي على تابع رئيسي بمثابة نقطة البدء
public static void main(String[] args) {
الدخل/الخرج
الخرج
استخدم ()System.out.println
لطباعة السطور النصيّة
System.out.println("Hello World!");
System.out.println(
"Integer: " + 10 +
" Double: " + 3.14 +
" Boolean: " + true);
استخدم ()System.out.print
للطباعة بدون سطر جديد
System.out.print("Hello ");
System.out.print("World");
استخدم ()System.out.printf
لتنسيق الطباعة بسهولة
System.out.printf("pi = %.5f", Math.PI); // => pi = 3.14159
الدخل
استخدم scanner
لقراءة الدخل، يجب استيراد الصف ;java.util.Scanner
Scanner scanner = new Scanner(System.in);
لقراءة السلاسل المحرفية المُدخلة
String name = scanner.next();
لقراءة البايتات المُدخلة
byte numByte = scanner.nextByte();
لقراءة العدد الصحيح المُدخل
int numInt = scanner.nextInt();
لقراءة العدد الحقيقي المٌدخل
float numFloat = scanner.nextFloat();
لقراءة العدد الحقيقي مضاعف الدقة المُدخل
double numDouble = scanner.nextDouble();
لقراءة القيمة المنطقية المُدخلة
boolean bool = scanner.nextBoolean();
المتغيرات
التصريح عن المتغيرات
يتم التصريح عن متغير باستخدام
// <type> <name> int fooInt;
يتم التصريح عن مجموعة من المتغيرات من نفس النوع
// <type> <name1>, <name2>, <name3> int fooInt1, fooInt2, fooInt3;
تهيئة المتغير
يتم تهيئة متغير باستخدام
// <type> <name> = <val> int barInt = 1;
يتم تهيئة مجموعة من المتغيرات من نفس النوع بنفس القيمة باستخدام
// <type> <name1>, <name2>, <name3> // <name1> = <name2> = <name3> = <val> int barInt1, barInt2, barInt3; barInt1 = barInt2 = barInt3 = 1;
أنواع المتغير
البايت (Byte
) : وهو 8bit ويستخدم لترميز الأعداد الصحيحة بين -128 و 127
byte fooByte = 100;
إذ كنت ترغب بتفسير البايت كعدد صحيح موجب (بدون إشارة). فإن هذه العملية البسيطة من الممكن أن تساعد
int unsignedIntLessThan256 = 0xff & fooByte;
هذا يناقض عمل cast الذي من الممكن أن يعطي عدد سالب
int signedInt = (int) fooByte;
القصير (Short
): وهو 16bit ويستخدم لترميز الأعداد الصحيحة بين -32,768 و 32,767
short fooShort = 10000;
الصحيح (Integer
): وهو 32bit ويستخدم لترميز الأعداد الصحيحة بين -2,147,483,648 و 2,147,483,647
int bazInt = 1;
الطويل (Long
): وهو 64bit ويستخدم لترميز الأعداد الصحيحة بين -9,223,372,036,854,775,808 و 9,223,372,036,854,775,807
long fooLong = 100000L;
يستخدم المحرف L
للدلالة على أن قيمة المتحول هي من النوع Long. و أي قيمة مُسندة للمتحول بدون استخدام L
هي عبارة عن عدد صحيح int
بشكل افتراضي.
ملاحظة: إن الأنواع byte
، short
، int
، long
، هي أنواع ذات إشارة signed. أي من الممكن أن تحوي على قيم موجبة أو قيم سالبة.
لا يوجد متغيرات بقيمة موجبة فحسب. ولكن المحارف تعتبر من نوعية unsigned ذات القيمة الموجبة فقط ذات 16bit.
العائم (Float
): وهو ذو دقة أحادية 32 bit IEEE 754 ويستخدم لترميز الأعداد الحقيقية ذات الفاصلة العائمة بين 149-^2 و 127^2 - (23-^2-2)
float fooFloat = 234.5f;
يستخدم المحرف f
أو F
للدلالة على أن قيمة المتحول هي من النوع Float
.
و إلا سيعتبر المتغير من النوع الحقيقي المضاعف.
المضاعف (Double
): وهو ذو دقة مضاعفة 64 bit IEEE 754 ويستخدم لترميز الأعداد الحقيقية ذات الفاصلة العائمة بين 1074-^2 و 1023^2 - (52-^2-2)
double fooDouble = 123.4;
القيم المنطقية (Boolean
) ذات القيمة: true
و false
boolean fooBoolean = true;
boolean barBoolean = false;
Char
هو محرف يونيكود 16بت أحادي
char fooChar = 'A';
لا يمكن أعادة تهيئة المعطيات من النوع final
final int HOURS_I_WORK_PER_WEEK = 9001;
ولكن من الممكن تهيئتها بعد عملية التصريح عنها
final double E;
E = 2.71828;
BigInteger
-عبارة عن نوع الأعداد الصحيحة الثابتة بمستويات دقّة مختلفة.
يستخدم نوع المعطيات BigInteger
للسماح للمبرمج بالتعامل مع الأعداد الصحيحة التي هي أكبر من 64-بت. حيث تُخزّن الأعداد الصحيحة في مصفوفة من البايتات، التي يمكن التلاعب بها باستخدام التوابع المبنيّة في الصف BigInteger
.
يمكن تهيئة المتغير من النوع BigInteger
بمصفوفة من البايتات أو بمصفوفة من السلاسل المحرفية.
BigInteger fooBigInteger = new BigInteger(fooByteArray);
BigDecimal
عبارة عن نوع الأعداد الحقيقية الثابتة بمستويات دقة مختلفة. ويأخذ المتغير من النوع BigDecimal
معاملين: عدد صحيح ذو حجم غير مقّيّد، يمثل مستوى الدقّة، وعدد صحيح أخر بحجم 32 بت.
يسمح النوع BigDecimal
بالتحكم بتقريب الأعداد الحقيقية. عندما يكون مطلوب مستوى دقة محدد للعدد الحقيقي يُنصح باستخدام BigDecimal
.
من الممكن تهيئة المتغير من النوع BigDecimal
بأحد الأنواع التالية: int
،long
،double
،String
،BigInteger
BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt);
كُن حذرًا عند استخدامك للأنواع float ,double لأن عدم الدقّة في تحديد النوع سوف تُنسخ في الـ BigDecimal
ويُفضل استخدام سلسلة محرفية ثابتة عندما تحتاج إلى قيمة دقيقة.
BigDecimal tenCents = new BigDecimal("0.1");
String -السلاسل المحرفية
String fooString = "My String Is Here!";
الحرف الخاص n\
يُعرف بحرف السطر الجديد الذي يحرك مؤشر الكتابة إلى بداية السطر التالي.
String barString = "Printing on a new line?\nNo Problem!";
الحرف الخاص t\
يُعرف بالمسافة الأفقية، يقوم بتحريك مؤشر الكتابة مسافة معينة إلى النقطة التالية في السطر.
String bazString = "Do you want to add a tab?\tNo Problem!";
System.out.println(fooString);
System.out.println(barString);
System.out.println(bazString);
بناء السلاسل المحرفية:
-
باستخدام عامل الجمع (+) تُعتبر الطريقة الأساسية (الأمثل) للقيام ببناء السلاسل المحرفية.
String plusConcatenated = "Strings can " + "be concatenated " + “via + operator.”; System.out.println(plusConcatenated); // Output: Strings can be concatenated via + operator.
-
باستخدام الصف
StringBuilder
لا تشكل هذه الطريقة أية سلاسل محرفية وسيطة، فقط تقوم بتخزين قطع السلاسل المحرفية و ربطها مع بعضها عندما يتم استدعاء التابع()toString
. تلميح: لا يعتبر الصفStringBuilder
إجرائية آمنة. يوجد صف بديل آمنStringBuffer
(مع تأثير بسيط على الأداء).
StringBuilder builderConcatenated = new StringBuilder(); builderConcatenated.append("You "); builderConcatenated.append("can use "); builderConcatenated.append("the StringBuilder class."); System.out.println(builderConcatenated.toString()); // فقط الآن تمّ بناء السلسة المحرفية // Output: You can use the StringBuilder class.
تكون StringBuilder
فعاله عندما السلسلة المحرفية الكاملة المبنيّة مطلوبة في نهاية عملية ما.
StringBuilder stringBuilder = new StringBuilder();
String inefficientString = "";
for (int i = 0 ; i < 10; i++) {
stringBuilder.append(i).append(" ");
inefficientString += i + " ";
}
System.out.println(inefficientString);
System.out.println(stringBuilder.toString());
تتطلب inefficientString
عمل أكثر، حيث أنها تنتج سلسلة محرفية عند كل دورة للحلقة. يتم ترجمة تجميع السلاسل المحرفية البسيطة بالعامل (+) إلى: toString()
و StringBuilder
تجنب استخدام تجميع السلاسل المحرفية داخل الحلقات.
-
لاستخدام منسق السلاسل المحرفية طريقة أخرى بديلة لتوليد السلاسل المحرفية سريعة و قابلة للقراءة.
String.format("%s may prefer %s.", “Or you”, “String.format()”); // Output: Or you may prefer String.format().
المصفوفات
يجب تحديد حجم المصفوفة بشكل فوري بمجرد التصريح عنها. تستخدم الصيغة التالية للتصريح عن مصفوفة.
// <datatype>[] <var name> = new <datatype>[<array size>]; // <datatype> <var name>[] = new <datatype>[<array size>];
int[] intArray = new int[10];
String[] stringArray = new String[1];
boolean boolArray[] = new boolean[100];
طريقة أخرى للتصريح عن مصفوفة و تهيئتها
int[] y = {9000, 1000, 1337};
String names[] = {"Bob", "John", "Fred", "Juan Pedro"};
boolean bools[] = {true, false, false};
فهرسة المصفوفة - الوصول إلى عنصر فيها
System.out.println("intArray @ 0: " + intArray[0]);
تبدأ المصفوفات بالفهرس (0)، و هي قابله للتغيير .
intArray[1] = 1;
System.out.println("intArray @ 1: " + intArray[1]) ArrayLists; // => 1
مجموعة من أنواع المعطيات الأخرى، التي تستحق التدقيق فيها:
ArrayLists : مشابهة للمصفوفات، إلا أنها تحوي على وظائف إضافية، وحجمها قابل للتعديل.
LinkedLists : عبارة عن تنفيذ لقائمة مترابطة بشكل مضاعف، التي تنفذ جميع العمليات التي من المتوقع لقائمة مترابطة بشكل مضاعف أن تنفذها.
Maps : عبارة عن وصل كائنات المفتاح إلى كائنات القيمة. وهي عبارة عن واجهة، و بالتالي لا يمكن أن يتم تشكيل كائنات منها. يجب أن يتم تحديد نوع المفاتيح و القيم بناءً على الكائن المُشكل من الصف.
من الممكن ان يُربط كل مفتاح إلى قيمة واحدة فقط، ومن الممكن أن يظهر كل مفتاح مرة واحدة فقط. (لا يوجد نسخ) لتنفيذ الخريطة/الواجهة Map
hashtable : يُستخدم هذا الصف الجدول ، HashMaps
وينفذ الخريطة Map ، هذا يسمح بتثبيت زمن العمليات الأساسية، مثل الحصول على عنصر أو إدخال عنصر، حتى في المجموعات الكبيرة.
TreeMap: عبارة عن Map ، مصنفة حسب مفاتيحها. يُحافظ كل تعديل على ترتيبه، إما باستخدام المقارن المزود عند عملية توليد الكائن، أو باستخدام المقارنات لكل كائن، اذا كان ينفذ واجهة قابلة للمقارنة. سوف يؤدي الفشل المدمج في تنفيذ واجهة قابلة للمقارنة، مع الفشل في تزويد مقارن إلى رمي ClassCastExceptions
تأخذ عمليات إدخال و حذف عناصر زمن من الدرجة ((O(log(n ، لذلك تجنب استخدام بنى المعطيات هذه، إلا أذا كنت ترغب من الاستفادة من ميزة الترتيب.
العمليات
System.out.println("\n->Operators");
int i1 = 1, i2 = 2; // الطريقة المختصرة للتصريح عن عدة متغيرات في نفس الوقت
العمليات الحسابية بسيطة
System.out.println("1+2 = " + (i1 + i2)); // => 3
System.out.println("2-1 = " + (i2 - i1)); // => 1
System.out.println("2*1 = " + (i2 * i1)); // => 2
System.out.println("1/2 = " + (i1 / i2)); // => 0 (int يعيد int/int)
System.out.println("1/2.0 = " + (i1 / (double)i2)); // => 0.5
باقي القسمة
System.out.println("11%3 = "+(11 % 3)); // => 2
عمليات المقارنة
System.out.println("3 == 2? " + (3 == 2)); // => false
System.out.println("3 != 2? " + (3 != 2)); // => true
System.out.println("3 > 2? " + (3 > 2)); // => true
System.out.println("3 < 2? " + (3 < 2)); // => false
System.out.println("2 <= 2? " + (2 <= 2)); // => true
System.out.println("2 >= 2? " + (2 >= 2)); // => true
العمليات المنطقية
System.out.println("3 > 2 && 2 > 3? " + ((3 > 2) && (2 > 3))); // => false
System.out.println("3 > 2 || 2 > 3? " + ((3 > 2) || (2 > 3))); // => true
System.out.println("!(3 == 2)? " + (!(3 == 2))); // => true
-
العمليات على مستوى البت
~ عامل إيجاد المتمم على مستولى البتات. << عامل الإزاحة الحسابية نحو اليسار (مع الأخذ بعين الاعتبار بت الإشارة). >> عامل الإزاحة الحسابية نحو اليمين (مع الأخذ بعين الاعتبار بت الإشارة). >>> عامل الإزاحة المنطقية نحو اليمين (بدون الأخذ بعين الاعتبار بت الإشارة). & على مستوى البتّات and العملية المنطقية ^ على مستوى البتّات xor العملية المنطقية | على مستوى البتّات or العملية المنطقية
عمليات الزيادة
int i = 0;
System.out.println("\n->Inc/Dec-rementation");
العامل ++ يقوم بالزيادة بمقدار واحد. العامل – يقوم بالإنقاص بمقدار واحد. إذا تم وضع هذين العاملين قبل المتغير، فإنهن يقومان بالزيادة أو الإنقاص، ومن ثم يعيدان قيمة المتحول الجديدة. أما إذا تم وضع هذين العاملين بعد المتغير، فإنهما يقومان بإعادة قيمة المتحول، ومن ثم يقومان بالزيادة أو الإنقاص.
System.out.println(i++); // i = 1, يطبع 0 (زياده لاحقة).
System.out.println(++i); // i = 2, يطبع 2 (زيادة سابقة).
System.out.println(i--); // i = 1, يطبع 2 (إنقاص لاحق)
System.out.println(--i); // i = 0, يطبع 0 (إنقاص سابق)
بنى التحكم
System.out.println("\n->Control Structures");
عبارة if
مشابهة لتلك الموجودة في لغة البرمجة C
int j = 10;
if (j == 10) {
System.out.println("I get printed");
} else if (j > 10) {
System.out.println("I don't");
} else {
System.out.println("I also don't");
}
حلقة While
int fooWhile = 0;
while(fooWhile < 100) {
System.out.println(fooWhile);
//زيادة العدّاد
//(في المجال (0،1،..99 foowhile مكررة 100 مرة ، حيث أن قيم المتغير
fooWhile++;
}
System.out.println("fooWhile Value: " + fooWhile);
حلقة Do While
int fooDoWhile = 0;
do {
System.out.println(fooDoWhile);
//زيادة العدّاد
//في المجال 0-99 foowhile مكررة 99 مرة ، حيث أن قيم المتغير
fooDoWhile++;
} while(fooDoWhile < 100);
System.out.println("fooDoWhile Value: " + fooDoWhile);
حلقة For
: هيكلية الحلقة على الشكل التالي:
for(<start_statement>; <conditional>; <step>)
مثال
for (int fooFor = 0; fooFor < 10; fooFor++) {
System.out.println(fooFor);
// fooFor 0->9 مكررة 10 مرات، حيث
}
System.out.println("fooFor Value: " + fooFor);
//outerيتم الخروج من الحلقة الداخلية باستخدام جملة الهروب المعنونّة بـ
outer:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (i == 5 && j ==5) {
break outer;
//يخرج من الحلقة الخارجية أيضا، بدلاً من الخروج فقط من الحلقة الداخلية
}
}
}
حلقة For Each
: قادرة على العمل مع المصفوفات و الكائنات for
إن حلقة التي تنفذ الواجهات القابلة للتكرار.
int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
هيكلية الحلقة على الشكل التالي:
for (<object> : <iterable>)
تقرأ هكذا: لكل عنصر في ال iterable
ملاحظة: يجب أن يتطابق نوع الكائن مع نوع عناصر ال iterable
for (int bar : fooList) {
System.out.println(bar);
//سوف تتكرر 9 مرات و يطبع 1-9 على سطور جديدة.
}
Switch
تعمل Switch
مع أنواع المعطيات: int
، char
، short
،byte
وأيضًا من الممكن أن تعمل مع النوع Enum
و String
و مجموعة من الصفوف الخاصة التي تجمع الأنواع البدائية: Character
, Byte
, Short
, Integer
. بدءًا من جافا 7، من الممكن استخدام النوع String
. ملاحظة: تذكر عدم استخدام التعليمة "break
" في نهاية حالة جزئية إذا كان هناك يوجد حالة أخرى تستوفي الشرط أيضًا.
int month = 3;
String monthString;
switch (month) {
case 1: monthString = "January";
break;
case 2: monthString = "February";
break;
case 3: monthString = "March";
break;
default: monthString = "Some other month";
break;
}
System.out.println("Switch Case Result: " + monthString);
عبارة (Try-with-resources
) في Java الإصدار +7
تُستخدم في جافا عبارات Try-catch-finally
، و لكن في جافا +7 أيضا ً مُتاح استخدام try-with-resources
إن عبارات try-with-resources
تُبسط عمل عبارات try-catch-finally
عن طريق إغلاق المصادر بشكل أتوماتيكي. لاستخدام try-with-resources
ضمّن كائن من صف في تعليمة try.
try (BufferedReader br = new BufferedReader(new FileReader("foo.txt"))) { // يمكنك أن تجرّب شيئًا يحتاج إلى استثناء System.out.println(br.readLine()); // في جافا 7 المصادر مغلقة دومًا حتى لو كان هناك استثناء } catch (Exception ex) { //catch سوف يتم إغلاق المصدر قبل أن تنفذ عبارة System.out.println("readLine() failed."); }
في هذه الحالة، لا يوجد حاجة إلى عبارة finally
حيث أن BufferedReader
تم إغلاقه للتو. يتم استخدام هذا لتجنب الحالات الحرجة، عندما عبارة finally
لا يمكن استدعاءها.
الاختزال الشرطي
يمكنك استخدام العامل "?
" لسرعة الأسناد . تُقرأ كما يلي: "إذا كانت العبارة صحيحة ، استخدم <أول قيمة> و إلا استخدم <القيمة الثانية>
int foo = 5;
String bar = (foo < 10) ? "A" : "B";
System.out.println("bar : " + bar); // "bar : A"تطبع
// صحيحة (foo < 10) لأن العبارة
//أو بشكل مبسط:
System.out.println("bar : " + (foo < 10 ? "A" : "B"));
التحويل بين أنواع المعطيات
تحويل المعطيات
تحويل السلاسل المحرفية إلى عدد صحيح
Integer.parseInt("123");//يعيد نسخة العدد الصحيح من السلسة المحرفية "123"
تحويل العدد الصحيح إلى سلسلة محرفية
Integer.toString(123);//يعيد النسخة المحرفية من العدد الصحيح 123
راجع تحويل المعطيات للأنواع التالية من الصفوف: Double Long String
الصفوف و التوابع
للتصريح عن كائن من الصف Bicycle
استخدم الكلمة المفتاحية new
Bicycle trek = new Bicycle();
استدعاء توابع الكائن
trek.speedUp(3); // setter , getter يجب عليك استخدام توابع الواضع و الآخذ
trek.setCadence(100);
يُعيد التابع ()toString
التمثيل النصي للكائن.
System.out.println("trek info: " + trek.toString());
التهيئة مزدوجة الأقواس لا تملك جافا تراكيب لتشكيل مجموعات ساكنة من المعطيات بطريقة سهلة عادةً يتم استخدام الطريقة التالية:
private static final Set<String> COUNTRIES = new HashSet<String>();
static {
COUNTRIES.add("DENMARK");
COUNTRIES.add("SWEDEN");
COUNTRIES.add("FINLAND");
}
ولكن يوجد طريقة أنيقة لإنجاز الشيء نفسه بشكل أسهل، تُدعى هذه الطريقة مزدوجة الأقواس
private static final Set<String> COUNTRIES = new HashSet<String>() {{
add("DENMARK");
add("SWEDEN");
add("FINLAND");
}}
يولد القوس الاول { } صف داخلي بدون اسم AnonymousInnerClass
ويعرّف القوس الثاني{ } كتلة مهيئ الحالة instance. يتم استدعاء هذه الكتلة، عندما يتم توليد الصف الداخلي لا يعمل هذا فقط للمجموعات، إنما يعمل أيضًا لكل الصفوف غير النهائي non-final
يمكنك تضمين صفوف أخرى خارجية غير عامة في ملف جافا ، ولكنها ليست بممارسة جيدة. بدلاً من ذلك يفضّل فصل الصفوف في ملفات جافا منفصلة
صيغة التصريح عن صف:
// <public/private/protected> class <class name> { // }
حقول البيانات, أنماط الباني, الوظائف كلها في الداخل
تستدعى الوظائف كالدوال في جافا
class Bicycle {
حقول و متغيرات الصف Bicycle
Public
: يمكن الوصول إليه من أي مكان
public int cadence;
Private
: يمكن الوصول إليه فقط من داخل الصف
private int speed;
Protected
: يمكن الوصول إليه فقط من داخل الصف و الصفوف الفرعية
protected int gear;
default
: يمكن الوصول إليه فقط من داخل الرزمة.
String name;
Static
متغير صف ساكن
static String className;
البلوك الساكن Static
لا تملك جافا تنفيذ للبواني الساكنة، ولكن جافا تملك كتل برمجية لتعريف متغيرات الصف (المتغيرات لساكنة) سيتم استدعاء هذا البلوك عند تحميل الصف.
static {
className = "Bicycle";
}
الباني هي الطريقة التي يتم فيها توليد الصفوف. هذا هو الباني
public Bicycle() {
//يمكنك أيضا استدعاء باني آخر:
// this(1, 50, 5, "Bontrager");
gear = 1;
cadence = 50;
speed = 5;
name = "Bontrager";
}
هذا عبارة عن باني ذو معاملات
public Bicycle(int startCadence, int startSpeed, int startGear,
String name) {
this.gear = startGear;
this.cadence = startCadence;
this.speed = startSpeed;
this.name = name;
}
صيغة الدالة
// <public/private/protected> <return type> <function name>(<args>)
أصناف الجافا غالبًا ما تنفّذ getters وsetters في حقولها
صيغة التصريح عن الدالة
// <access modifier> <return type> <method name>(<args>)
public int getCadence() {
return cadence;
}
دوال void
لا تحتاج تصريح عودة
public void setCadence(int newValue) {
cadence = newValue;
}
public void setGear(int newValue) {
gear = newValue;
}
public void speedUp(int increment) {
speed += increment;
}
public void slowDown(int decrement) {
speed -= decrement;
}
public void setName(String newName) {
name = newName;
}
public String getName() {
return name;
}
دالة لتوليد قيم الصفات لهذا الكائن
@Override // موروثة من الصف لهذا الكائن.
public String toString() {
return "gear: " + gear + " cadence: " + cadence + " speed: " + speed +
" name: " + name;
}
الصف PennyFarthing
عبارة عن صنف فرعي من Bicycle
class PennyFarthing extends Bicycle {
-Penny Farthings //هي عباره عن نوع من الدراجات بعجلات أمامية كبيرة.
public PennyFarthing(int startCadence, int startSpeed) {
// super استدعي الباني الأب باستخدام الكلمة المفتاحية
super(startCadence, startSpeed, 0, "PennyFarthing");
}
يجب عليك تعليم المنهج الذي تُعيد كتابته بـ annotation@
.
@Override
public void setGear(int gear) {
this.gear = 0;
}
Object casting
بما أن الصف PennyFarthing
يرث الصف Bicycle
: فمن الممكن القول أن: Bicycle
هو PennyFarthing
، و يمكن أن نكتب:
// Bicycle bicycle = new PennyFarthing();
هذا يُدعى"object casting
" حيث يتم تشكيل كائن من كائن آخر.
الواجهات
صيغة التصريح عن واجهة
// <access-level> interface <interface-name> extends <super-interfaces> { // // Constants // // Method declarations // }
مثال - الطعام:
public interface Edible { public void eat(); //يجب على أي صف ينفذ هذه الواجهة // ان ينفذ هذه الدالة }
public interface Digestible { public void digest(); // منذ جافا 8، من الممكن أن تملك الواجهات دالة افتراضية. public default void defaultMethod() { System.out.println("Hi from default method ..."); } }
الآن يمكنك تشكيل صف يُنفذ كلا من هاتين الواجهتين.
public class Fruit implements Edible, Digestible {
@Override
public void eat() {
// ...
}
@Override
public void digest() {
// ...
}
}
في جافا، يمكنك أن تمدد(ترث) صف واحد فقط، ولكن يمكنك أن تنفذ عدّة واجهات . على سبيل المثال:
public class ExampleClass extends ExampleClassParent implements InterfaceOne,
InterfaceTwo {
@Override
public void InterfaceOneMethod() {
}
@Override
public void InterfaceTwoMethod() {
}
}
الصفوف التجريدية
صيغة التصريح عن صف تجريدي:
// <access-level> abstract class <abstract-class-name> extends // <super-abstract-classes> { // // Constants and variables // // Method declarations // }
لا يمكن تشكيل كائنات من الصفوف المجردة (تمثيل الصفوف المجردة)
يمكن للصفوف المجردة أن تعرف عن دوال مجرّدة. المناهج المجردة لا تحوي على جسم ويجب تعليمها بالكلمة المفتاحية abstract
. يجب على الصفوف الأبناء غير المجردة أن تعيد كتابة Override@
جميع الدوال المجردة في صفوفها العليا.
من الممكن أن تكون الصفوف المجرّدة مفيدة عند الجمع بين منطق التكرار و السلوك المخصص، ولكن بما أن الصف المجرد يتطلب الوراثة، فإن الصفوف المجردة تنتهك منطق "التركيب عبر الوراثة". لذلك خُذ بعين الاعتبار الطرق الأخرى التي تستخدم هذا التركيب
public abstract class Animal
{
private int age;
public abstract void makeSound();
من الممكن أن يحوي المنهج جسم
public void eat()
{
System.out.println("I am an animal and I am Eating.");
//(private)ملاحظة: من الممكن هنا الوصول للمتغيرات الخاصة
age = 30;
}
public void printAge()
{
System.out.println(age);
}
يمكن أن تحوي الصفوف المجردة على دالة رئيسية
public static void main(String[] args)
{
System.out.println("I am abstract");
}
}
class Dog extends Animal { لاحظ بأنه لا يزال هناك حاجة لإعادة كتابة الدوال التجريدية في الصف التجريدي // @Override public void makeSound() { System.out.println("Bark"); // age = 30; ==> ERROR! // Animal خاص بالنسبة للصف age خطأ- و ذلك لأن المتغير }
ملاحظة: من الممكن أن تحصل على خطأ إذا قمت هنا باستخدام Override@
لأن جافا لا تسمح لك بإعادة كتابة الدوال الساكنة. ما يحدث هنا يُدعى إخفاء الدالة METHOD HIDING
public static void main(String[] args)
{
Dog pluto = new Dog();
pluto.makeSound();
pluto.eat();
pluto.printAge();
}
الصفوف النهائية final class
صيغة التصريح عن الصفوف النهائية
// <access-level> final <final-class-name> { // // Constants and variables // // Method declarations // }
الصفوف النهائية هي عبارة عن الصفوف التي لا يمكن وراثتها، (أي هي الولد النهائي). بطريقة ما، تُعد الصفوف النهائية معاكس الصفوف المجردة. لأنه يجب توسيع (وراثة) الصفوف المجردة، أما الصفوف النهائية لا يمكن توسيعها.
public final class SaberToothedCat extends Animal { لاحظ بأنه ما يزال يوجد حاجة لإعادة كتابة الدوال المجردة في الصف المجرد.// @Override public void makeSound() { System.out.println("Roar"); } }
الدوال النهائية
public abstract class Mammal() { // صيغة الدالة النهائية: // <access modifier> final <return type> <function name>(<args>) // لا يمكن إعادة كتابة الدوال النهائية بواسطة صف ابن، // وبالتالي الدالة النهائية هو أخر تنفيذ للدالة . public final boolean isWarmBlooded() { return true; } }
النوع Enum
еnum
هي طريقة تنظيمية للثوابت (Constants) في الكود بحيث تجمع الثوابت التي لها علاقة ببعضها تحت فئة واحدة بطريقة تنظم الوصول إليها .بما أن هذه القيم هي عبارة عن ثوابت، لذلك فإن أسماء الحقول من النوع enum
يجب أن تكتب بحروف كبيرة. في لغة جافا يتم تعريف هذا النوع باستخدام الكلمة المفتاحية enum
. لتعريف متحول عن يوم من أيام الأسبوع، باستخدام النوع enum
:
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
من الممكن استخدام متغيرنا Day من النوع enum
كما يلي:
public class EnumTest {
//Enumالمتغير من النوع
Day day;
public EnumTest(Day day) {
this.day = day;
}
public void tellItLikeItIs() {
switch (day) {
case MONDAY:
System.out.println("Mondays are bad.");
break;
case FRIDAY:
System.out.println("Fridays are better.");
break;
case SATURDAY:
case SUNDAY:
System.out.println("Weekends are best.");
break;
default:
System.out.println("Midweek days are so-so.");
break;
}
}
public static void main(String[] args) {
EnumTest firstDay = new EnumTest(Day.MONDAY);
firstDay.tellItLikeItIs(); // => Mondays are bad.
EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
thirdDay.tellItLikeItIs(); // => Midweek days are so-so.
}
}
الأنواع enum
هي فعالة بشكل أكبر مما تم توضيحه فوق. من الممكن أن يحتوي جسم المتغير enum
على دوال و حقول أخرى.
ترجمة -وبتصرّف- للمقال Learn Java in Y Minutes
أفضل التعليقات
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.