Object-Oriented Programming

  • Java – Creating Moon Class Required for Planet

    لديك اثنين من الفصول في برنامجك، الفصل planet والفصل moon. تريد جعل الفصل moon مرتبطًا بشكل إجباري بالفصل planet، حيث يجب أن يتم إنشاء كائن من الفصل moon بعد إنشاء كائن من الفصل planet.

    الطريقة لتحقيق هذا هي عن طريق تمرير كائن من الفصل planet كمعلمة إلى الفصل moon عند إنشاء كائن moon. إليك كيف يمكن تعديل الفصل moon لتحقيق ذلك:

    java
    public class Moon extends Planet { private String moonName; public Moon(String moonName, Planet planet, double rotationHours, double revolutionDays) { super(planet.getPlanetName(), rotationHours, revolutionDays); this.moonName = moonName; } }

    وفي هذا السياق، تحتاج إلى ضبط الاسماء الخاصة بالفصول planet و moon لتتوافق مع قواعد تسمية الكلاسات في جافا. يفضل استخدام الحروف الكبيرة للحرف الأول من اسم الفصل (مثل Planet بدلاً من planet)، واستخدام كلمة أسماء تجمع بين الكلمات (camel case) للأسماء المتعددة الكلمات (مثل moonName بدلاً من namaBulan)، واستخدام الأسماء الواضحة والمفهومة للمتغيرات والدوال.

    المزيد من المعلومات

    بالتأكيد! إليك بعض المعلومات الإضافية حول الكود:

    1. استخدام الوراثة: بواسطة استخدام كلمة المفتاح extends في تعريف الفصل Moon، تُظهر أن Moon يرث من Planet، مما يعني أن Moon يحصل على جميع السمات والسلوكيات من Planet.

    2. استخدام super(): عند استخدام super() في مُنشئ Moon، يُمرِّر الأرغومنتات إلى مُنشئ Planet الذي يُنشأ الجزء الأب من Moon، ويُضمن أن يتم استدعاء مُنشئ Planet قبل تنفيذ أي شيء آخر في مُنشئ Moon.

    3. استخدام المتغيرات الخاصة: تستخدم المتغيرات الخاصة مثل moonName و planetName لتخزين معلومات الكواكب والأقمار بشكل منفصل، وتمكين الوصول إليها من داخل كل فصل بشكل مستقل.

    4. استخدام الدوال العامة: تستخدم الدوال العامة مثل getPlanetName() للحصول على اسم الكوكب، مما يتيح إمكانية الوصول إليها من خارج الفصل بطريقة منظمة وآمنة.

    5. تنسيق الأكواد: تنسيق الأكواد بشكل جيد يجعلها أكثر قراءة وفهمًا، مما يسهل على الآخرين وعلى نفسك فهم الكود وصيانته في المستقبل.

    إذا كنت بحاجة إلى أي معلومات أخرى أو لديك أسئلة إضافية، فلا تتردد في طرحها!

  • تحليل أداء التعددية الثابتة في C++ باستخدام Boost Variant وطرق التصفية المختلفة

    في هذا المقال، سنقوم بفحص ومقارنة أداء ثلاثة أساليب لتحقيق التعددية في لغة البرمجة C++، وذلك باستخدام boost variants وزيارات متعددة. الأساليب المدروسة هي:

    1. Static Polymorphism باستخدام boost variants مع زائر منفصل لكل طريقة:
      في هذه الطريقة، تم استخدام boost variants لتمثيل مجموعة متنوعة من الأشكال، وتم إنشاء زائر (visitor) منفصل لكل طريقة معينة (rotate و spin).

    2. Static Polymorphism باستخدام boost variants مع زائر واحد يستخدم تحميل الطريقة المختلفة:
      في هذه الطريقة، تم استخدام boost variants أيضًا، ولكن تم إنشاء زائر واحد يستخدم تقنية تحميل الطريقة المختلفة (method overloading) لاستدعاء الطريقة المناسبة.

    3. Dynamic Polymorphism الكلاسي:
      تم استخدام التعددية الديناميكية الكلاسيكية باستخدام وظائف افتراضية في الواجهة الخاصة بالأشكال.

    المنصة والأدوات المستخدمة:

    • المنصة: Intel x86 64 بت، Red Hat، معالج متعدد النوى، 32 غيغابايت من الذاكرة العشوائية.
    • المترجم: GCC 4.8.1 مع تحسين -O2.
    • Boost: الإصدار 1.6.0.

    النتائج الأولية:

    • أظهرت النتائج أن الطريقة الأولى (Static Polymorphism مع زائر منفصل لكل طريقة) كان لديها أداءًا أفضل بشكل ملحوظ من الطريقتين الأخريين.
    • كما لوحظ أن الطريقة الديناميكية (Dynamic Polymorphism) كانت تفوق غالبًا على الطريقة الثانية (Static Polymorphism مع زائر واحد يستخدم تحميل الطريقة المختلفة).

    تحليل الأداء:

    • يمكن أن يكون الأداء الأفضل للطريقة الأولى مرده إلى تفوق boost variants في إدارة التعددية بشكل فعال.
    • بالنسبة للطريقة الثانية، يمكن أن يكون هناك تكلفة إضافية ناتجة عن مرور معامل إضافي لتحديد أي طريقة يجب استدعاؤها، وربما هناك فروع إضافية بسبب تحميل الطريقة المختلفة.
    • قد يكون الأداء الجيد للطريقة الديناميكية مفسرًا بسهولة التحكم في تعديل الأشكال في وقت التشغيل.

    السؤال:

    • يتساءل الكاتب عن سبب أداء الطريقة الثانية (Static Polymorphism مع زائر واحد يستخدم تحميل الطريقة المختلفة) الذي كان أداءه أسوأ من الطريقة الديناميكية، حيث كان من المتوقع أن يكون التعددية الثابتة تفوق التعددية الديناميكية.

    تحليل السؤال:

    • يمكن أن يكون أداء الطريقة الثانية أسوأ بسبب التكلفة الإضافية لتحديد الطريقة المناسبة باستخدام تحميل الطريقة المختلفة، وربما تكون هناك فروع إضافية ناتجة عنه.
    • قد يكون هناك تأثير سلبي على الأداء ناتج عن تحميل الطريقة المختلفة، خاصةً إذا كان هناك عدد كبير من الطرق المختلفة يمكن استدعاؤها.

    الختام:

    • يجب مواصلة التجارب وفحص الكود بمزيد من التفصيل لفهم تفاصيل الأداء والتأثيرات الدقيقة.
    • يمكن استكشاف تحسينات إضافية في الكود لتحسين أداء الطرق المختلفة.
    • قد يكون من المفيد استخدام أدوات تحليل الأداء لتحديد النقاط الساخنة وتحسينها.

    المزيد من المعلومات

    في هذا السياق، يتم استعراض أداء ثلاثة أساليب لتحقيق التعددية في لغة C++، حيث يتم التركيز على استخدام مكتبة Boost variant لتحقيق التعددية الثابتة (Static Polymorphism) والتعددية الديناميكية (Dynamic Polymorphism). تُظهر الطرق الثلاثة كالآتي:

    1. Static Polymorphism using Boost Variants with Separate Visitor for Each Method (Method [1]):
      يتم استخدام مكتبة Boost variant مع إنشاء مستندات فرعية (visitors) منفصلة لكل طريقة (rotate و spin).

    2. Static Polymorphism using Boost Variants with Single Visitor using Method Overloading (Method [2]):
      يتم استخدام مكتبة Boost variant أيضًا، ولكن هنا يتم استخدام مستند (visitor) واحد يستخدم تقنية التحميل الزائد (method overloading) لاستدعاء الوظائف المختلفة (rotate و spin).

    3. Dynamic Polymorphism (Method [3]):
      تُستخدم وظائف افتراضية في واجهة IShape لتحقيق التعددية الديناميكية.

    تمت ملاحظة بعض النتائج الهامة من هذه المقارنة:

    • يظهر أن Method [1] يتفوق بشكل كبير على Methods [2] و [3].
    • Method [3] يتفوق على Method [2] في معظم الحالات.

    المبرر الذي قدمه السائل يتعلق بأداء Method [2]، حيث يتوقع أن يكون التعدد الثابت أفضل أداءًا من التعدد الدينامي. ومع ذلك، يشير إلى أن Method [2] يظهر أداءً أقل من التعدد الدينامي. يعزى هذا إلى تكلفة البارامتر الإضافي الذي يتم تمريره في Method [2] لتحديد أي visit() يجب استدعاؤه، وربما بعض التفرعات الإضافية نتيجة لتقنية التحميل الزائد.

    يُرفق مع المقالة كود برمجي يحتوي على تعريفات للكلاسات والمستندات المستخدمة في التجربة، بالإضافة إلى دوال رئيسية (make_virtual_shapes, make_template_shapes, make_template_shapes_single) التي تقوم بتنفيذ التعددية بأساليب مختلفة، ويتم قياس وقت تنفيذ كل طريقة باستخدام Boost chrono.

    السائل يطرح سؤالًا حول سبب أداء Method [2] الذي يستخدم زائر واحد ولكن يعتمد على تقنية التحميل الزائد لاستدعاء الوظائف، ويتساءل عما إذا كان يجب ألا يكون هذا الأداء أفضل من وظائف الفيرتشوال.

  • Java 8: Mastering Method References

    في عالم برمجة Java 8، تقدم لنا الميزة الرائعة للـ Method References طريقة أنيقة للتعبير عن الدوال. وفي سياق سؤالك حول كيفية استخدام method reference بناءً على method reference آخر، يجب أولاً أن نتفهم كيف يعمل الأمر.

    لديك كلاس Person الذي يحتوي على خاصية sibling و age. الفكرة هي الحصول على قائمة من أعمار الأشقاء باستخدام تعبيرات Method References. في المثال الذي قدمته، قمت بذكر أن الكود التالي يعمل:

    roster.stream().map(p -> p.getSibling().getAge()).collect(Collectors.toList());
    

    والآن، تساؤلك هو هل يمكن القيام بذلك باستخدام method references بطريقة أكثر أناقة؟

    في Java، لا يمكنك استخدام method reference مباشرة على method reference آخر كما في المثال الذي قدمته:

    roster.stream().map(Person::getSibling::getAge).collect(Collectors.toList());
    

    في هذا السياق، يمكن استخدام method reference على method reference إذا كانت الدالة المستهدفة هي static، ولكن لا يمكن استخدامها في حال كانت الدالة تتطلب كائنًا.

    لذا، يمكنك استخدام method reference بطريقة أخرى مشابهة للمثال الذي قدمته، مثل:

    roster.stream().map(p -> p.getSibling().getAge()).collect(Collectors.toList());
    

    هذا يضمن الوصول إلى الأشقاء ومن ثم الحصول على الأعمار بطريقة فعّالة. في النهاية، يظل استخدام method reference قرارًا بين قراءة الكود وفهمه، وتحقيق الأداء المناسب.

    المزيد من المعلومات

    الآن، سنقوم بتوسيع المحادثة وإضافة المزيد من المعلومات حول تعبيرات Method References في Java 8 وكيف يمكن استخدامها بطرق مختلفة.

    تعتبر تعبيرات Method References جزءًا أساسيًا من ميزة Lambda expressions في Java 8، وهي تسهل على المطورين كتابة الشيفرة بشكل أنظف وأقل تعقيداً. يسمح Method References بالربط بين اللامبدا والدوال الموجودة بالفعل في البرنامج. هذا يسهل فهم الشيفرة وجعلها أقل إزعاجاً.

    هناك ثلاثة أنواع رئيسية من Method References في Java:

    1. مراجعة إلى static method: يمكنك استخدامها عندما يحتاج اللامبدا إلى استدعاء static method. على سبيل المثال:
    List<String> myList = Arrays.asList("Java", "C++", "Python");
    myList.forEach(System.out::println);
    

    هنا، نستخدم Method Reference للإشارة إلى static method println من System.out.

    1. مراجعة إلى دالة مثيلة: يمكنك استخدامها عندما يحتاج اللامبدا إلى استدعاء دالة مثيلة. على سبيل المثال:
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    int sum = numbers.stream().reduce(0, Integer::sum);
    

    هنا، يتم استخدام Method Reference للإشارة إلى دالة مثيلة Integer::sum.

    1. مراجعة إلى دالة من أحد أفرع الكائن: يمكنك استخدامها عندما يحتاج اللامبدا إلى استدعاء دالة من كائن محدد. على سبيل المثال:
    List<Person> roster = ...; // assume you have a list of Person objects
    roster.stream().map(Person::getAge).collect(Collectors.toList());
    

    هنا، يتم استخدام Method Reference لاستدعاء دالة getAge من كل كائن من قائمة الأشخاص.

    إلى جانب ذلك، يمكنك الجمع بين Method References وتركيب اللامبدا للوصول إلى مزيد من المرونة. ومع ذلك، يجب عليك أن تكون حذرًا عند استخدامها للتأكد من أن الشيفرة لا تفقد وضوحها وصيانتها.

    في الختام، يظل استخدام Method References أداة قوية في جعل الشيفرة أكثر قراءةً وصيانةً، وتساهم في جعل برمجة Java 8 أكثر فعالية.

  • أساسيات البرمجة في جافا: فهم الطريقة الرئيسية وتعريف الدوال

    في عالم لغة البرمجة جافا، يعد الطريقة الرئيسية (main method) هو نقطة بداية تنفيذ البرنامج. تستخدم لتنظيم تدفق التحكم في البرنامج وتوجيه التنفيذ إلى الأجزاء المختلفة من الشيفرة. إلا أنه، ووفقاً للمعايير والقواعد في لغة جافا، لا يمكن تعريف الدوال داخل الدالة الرئيسية.

    في المثال الذي قدمته، حاولت تعريف دالة cal2 داخل الطريقة الرئيسية، ولكن هذا ليس مسموحًا في جافا. الدوال يجب أن تتم إعلانها وتحديدها داخل الهيكل الخارجي للدالة الرئيسية، أي خارج نطاق تعريف الدالة الرئيسية.

    التركيبة الصحيحة تكون كالتالي:

    java
    class R { public int cal(int a, int b) { return a + b; } public int cal3(int a, int b) { return a * b; } } public class Rect { // دالة البداية public static void main(String arg[]) { // تعريف واستخدام الدالة cal2 int ab2 = cal2(2, 2); System.out.println(ab2); // إنشاء كائن من الفئة R R r = new R(); // استخدام الدالة cal وطباعة الناتج int ab = r.cal(2, 2); System.out.println(ab); // استخدام الدالة cal3 وطباعة الناتج int ab3 = r.cal3(2, 3); System.out.println(ab3); } // تعريف الدالة cal2 خارج الدالة الرئيسية public static int cal2(int a, int b) { return a + b; } }

    هكذا، يمكنك تعريف الدوال في الجزء الخارجي للدالة الرئيسية واستخدامها بشكل صحيح داخلها. يسمح ذلك بتنظيم الشيفرة وإعادة استخدام الدوال بشكل فعال.

    المزيد من المعلومات

    بالطبع، دعونا نقم بتوسيع المناقشة حول الشيفرة المقدمة ونعرض بعض المفاهيم الأساسية في لغة البرمجة جافا.

    في البداية، يجب أن نفهم أن الطريقة الرئيسية (main method) هي نقطة البداية لتنفيذ برنامج جافا. يتم تنفيذ الأوامر الموجودة داخلها عند بدء تشغيل البرنامج. في مثالك، تم استخدام الطريقة الرئيسية لإنشاء كائن من الفئة R واستخدام بعض الدوال المعرفة داخلها.

    الفئة R تحتوي على اثنتين من الدوال: cal و cal3. الدالة cal تقوم بجمع قيمتين، في حين تقوم الدالة cal3 بضربهما. هذه الدوال تعد أمثلة بسيطة على كيفية تعريف واستخدام الدوال في جافا.

    عندما قمت بتعليق الكود الذي يحتوي على محاولة تعريف دالة داخل الطريقة الرئيسية، كنت على حق في أنها لا يمكن أن تعمل بهذه الطريقة. الدوال يجب أن تتم إعلانها خارج الدالة الرئيسية لتكون متاحة للاستخدام في أماكن أخرى في البرنامج.

    من الجدير بالذكر أن استخدام الكود المعتمد على الكائنات (Object-Oriented Programming) يشكل جزءًا أساسيًا من جافا، حيث يمكنك إنشاء كائنات من الفئات واستخدامها لتنفيذ العديد من الأوامر. في مثالك، قمت بإنشاء كائن R واستخدامه لاستدعاء الدوال المعرفة في هذه الفئة.

    يمكن أيضا أن يكون هناك بعض التحسينات في الشيفرة، مثل استخدام تسميات مناسبة للمتغيرات وإضافة تعليقات لشرح الشيفرة. هذا يساعد في فهم الشيفرة بسهولة وصيانتها في المستقبل.

    لذلك، يُشجع دائمًا على كتابة شيفرة نظيفة ومنظمة، واستخدام تصميم موجه للكائنات لتسهيل فهم الشيفرة وتحسين إعادة استخدام الكود.

  • حل مشكلة Illegal Start of Expression في Java

    عنوان الموضوع: “بداية غير قانونية للتعبير في كود البرمجة: فهم عميق وأثرها على تنفيذ البرامج”

    في عالم البرمجة، تواجه المطورين أحيانًا تحديات تقنية معينة يجب عليهم فهمها جيدًا لضمان أداء البرامج بشكل صحيح. أحد هذه التحديات هو رسالة الخطأ المعروفة باسم “Illegal start of expression”، والتي تشير إلى بداية غير قانونية لتعبير في كود البرمجة.

    تفسير هذه الرسالة يتطلب فهمًا عميقًا للغة البرمجة Java وأساسياتها. يبدأ الأمر بالنظر في الشيفرة التي قدمتها، حيث يتبين أنها تحتوي على كلاس بسيط يسمى “Test”. ولكن هناك خطأ في تنظيم الشيفرة داخل دالة “main”، حيث يتم فتح الدالة دون إغلاقها، مما يؤدي إلى حدوث الخطأ.

    لحل هذا المشكلة، يجب غلق دالة “main” بشكل صحيح، مما يؤكد على هيكلية صحيحة للشيفرة. يمكن تصحيح الشيفرة كما يلي:

    java
    import java.text.*; import java.util.*; public class Test { public static void main(String args[]) { // يمكنك هنا استدعاء الدالات أو كتابة الكود الخاص بك } public void sample() { System.out.println("Hello Working ...."); } }

    تحل هذه التعديلات مشكلة “Illegal start of expression” وتجعل الشيفرة صحيحة من الناحية النحوية. ومن هنا يمكن للمطور الاستمرار في تطوير برنامجه بشكل سلس، بدون أية مشاكل في التنفيذ.

    إن فهم هذه الرسالة والتعامل معها يعزز مهارات المبرمج ويساهم في إنشاء برمجيات قوية وخالية من الأخطاء.

    المزيد من المعلومات

    في تعميق فهمنا لرسالة “Illegal start of expression” في لغة البرمجة Java، يجب أن نتناول بعض النقاط المهمة التي قد تساهم في تعزيز معرفتنا بالموضوع.

    أولاً وقبل كل شيء، ينبغي أن نتأكد من أن الفهم الأساسي للهيكل الأساسي للغة Java موجود. Java هي لغة برمجة تعتمد على كائنات (Object-Oriented)، ويتم تنفيذ البرامج فيها عن طريق تعريف كلاسات ودوال. الكلاس الرئيسي الذي يتم تنفيذه في برنامج Java يحتوي عادة على دالة main التي تعتبر نقطة البداية لتنفيذ البرنامج.

    عندما نواجه خطأ “Illegal start of expression”، فإنه يشير إلى وجود خلل في التركيب النحوي للكود. في السياق الذي قدمته، كانت المشكلة تكمن في فتح دالة main بشكل صحيح، ولكن لم يتم إغلاقها بشكل صحيح، مما تسبب في الخطأ.

    من الجدير بالذكر أن هناك أسبابًا أخرى لظهور رسالة “Illegal start of expression” قد تشمل وجود أخطاء في الأقواس، أو استخدام الكلمات الرئوية في السياق غير المناسب، أو ترك متغير غير مغلق بشكل صحيح.

    لتفادي هذه الأخطاء، يفضل دائما فحص الشيفرة بعناية واستخدام أدوات تحليل الكود ومترجمات اللغة لضمان أن البرنامج يتبع بنية اللغة الصحيحة. يعزز فهم هذه النقاط المطورين ويساهم في إنتاج برمجيات قوية ومستقرة.

زر الذهاب إلى الأعلى
إغلاق

أنت تستخدم إضافة Adblock

يرجى تعطيل مانع الإعلانات حيث أن موقعنا غير مزعج ولا بأس من عرض الأعلانات لك فهي تعتبر كمصدر دخل لنا و دعم مقدم منك لنا لنستمر في تقديم المحتوى المناسب و المفيد لك فلا تبخل بدعمنا عزيزي الزائر