الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

انتقل من ++C إلى جافا بسلاسة ... 3

بدأه مصطفى 36a2 في 27 أغسطس 2013 · 5 رد · 1,408 مشاهدة · في JavaEE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع
السلام عليكم ورحمة الله وبركاته
قمنا في الحلقتين السابقتين بتغطية لمعظم الأفكار في اختلافات جافا عن ++C
وسنختم الحلقتين السابقتين ..بهذه الحلقة إن شاء الله ..
سنتحدث عن البرمجة كائنية التوجه ..object oriented programming .. طبعاً المفاهيم البرمجية هي ذاتها أينما ذهبنا .. ولكن تختلف في التطبيق ..
وفيما يلي قائمة ببعض الاختلافات التي استطعت إيجادها ...باختصار
1-محددات الوصول Access Modifiers والتي تحدد صلاحية استخدام المتحولات والتوابع خارج الصف
في ++C
 

 

اقتباس
Access          : public    protected    private
Same class      :   yes      yes           yes
Derived classes :   yes      yes         no
Outside classes :   yes      no          no
 

 

 

المفهوم نفسه وبالنسبة لجافا فالجدول التالي يوضح محددات الوصول فيها ... ( وتختلف بوجود حالة no modifier )
 

 

اقتباس
Modifier        | Class | Package | Subclass | World
public           |  yes    |   yes      |   yes      |  yes
protected     | yes     |   yes      |   yes      |  no
no modifier  | yes     |   yes     |   no        |  no
private          |  yes     |   no      |   no        |  no
 

 

 

أما عن استخدامها : 
في لغة ++C :
public:int a,b,c;int function(){return 0;}
أما في java
public int a,b,c;public int function(){return 0;}
2-الوراثة Inheritance ... تختلف بأمرين ... في ++C يمكن الوراثة من أكثر من صف في نفس الوقت ... أما في جافا فلا يمكن الوراثة إلا من صف واحد ..(ولكن هناك طريقة أخرى لذلك)
في ++C 
class A { /* ... */ };
class B { /* ... */ };
class C { /* ... */ };
class X : public A, private B, public C { /* ... */ };
في جافا نستخدم الكلمة المفتاحية extends  أي امتداد ..
public class A{}
public class B extends A{}
public class C extends B{}
public class X extends C{}
للتذكرة .. وراثة صف لصف آخر تؤدي إلى احتواء الصف الجديد على نفس مكونات الصف القديم (العامة والمحمية فقط)
في جافا نستخدم العملية instanceof لمعرفة :هل الكائن المنشأ من صف ما هو وارث لصف آخر ؟ وتعطي true أو false
 
ثانيا ... تستخدم java مفهوم الواجهة interface  كصفوف مجردة ..يمكن وراثتها ... وتستخدم الكلمة المفتاحية implements بدلاً من extends لوراثة واجهة وسنتحدث عنها بعد قليل ..
 
3-التجريد Abstraction ...
لإنشاء صف مجرد .. في جافا نستخدم الكلمة المفتاحية abstract قبل كلمة class عند تعريف الصف ..
والصف المجرد لا يمكن انشاء كائنات منه فهو مجرد (أي ليس له علاقة بالتطبيق ... بل بالمفهوم بشكل عام)
ولكن يمكن وراثته .. وبعد ذلك يمكن أن ننشئ الكائنات من أبنائه :)
في ++C يكفي أن يكون هناك تابع واحد مجرد ليكون الصف كله مجرداً
class Animal
{
  public:
    virtual int GetNumberOfLegs() = 0;
};
في جافا :
abstract class d{ }
الصف السابق لا يمكن إنشاء كائنات منه ولكن يمكن وراثته ثم إنشاء الكائنات من الأبناء
ملاحظة: إذا كنت تتساءل عن جدوى ذلك .. فأنصحك بالبحث عن Design Patterns
أخيراً ...يمكن أن تعتبر الواجهة interface صفاً مجرداً ..أي لا يمكن إنشاء كائنات منها ..ولكن يمكن وراثتها باستخدام الكلمة المفتاحية implements ثم يمكن إنشاء كائن من الصف الوارث
ولكن الفرق بين الصف المجرد وبين الواجهة ... أن الصف المجرد يمكن كتابة جسم لتوابعه ...
أما الواجهة فلا يسمح بكتابة جسم للتابع فيها ... (يجب دراسة Design patterns لفهم فوائد هذه التطبيقات ) .. كما انها لا يمكن ان تحوي متغيرات ... ثوابت فقط
كما أن الوراثة من الواجهة تجبر الصف الوارث على بناء التوابع جميعا(حتى لو تركت الجسم فارغا) ... أما الوراثة من صف آخر فلك الحرية في إعادة كتابة الدوال التي تريدها للتخطي توابع الآباء أو لا ... 
كما يمكننا وراثة أكثر من واجهة واحدة .. وهذا يقابل الوراثة المتعددة في ++C تقريبا
interface a{
void w();
}
interface b{
void s();
}
class c implements a,b{
public void s(){}
public void w(){}
}
 
4- تعدد الأوجه Polymorphism ... ومن تطبيقاته التحميل الزائد للتوابع (بشكل عام ) والتخطي (بشكل خاص)
التحميل الزائد للتوابع يمكننا استخدامه داخل الصف نفسه ..(كما أنه لا يوجد في جافا تحميل زائد للعمليات) ..
التخطي Override  ... وهو من أهم المفاهيم الكائنية التوجه .. ويعني تخطي الأبناء لتوابع الآباء .. وهو نفس مفهوم التحميل الزائد
إلا أنه ضمن عملية الوراثة ويستحسن عند القيام بـoverride كتابة الكلمة @override قبل التابع  ليكون واضحاً أن هذا التابع موجود في الأب قبل ذلك ..
فيما يلي مثال بوراثة متسيط .. يكافئ تقريبا عملية وراثة متعددة من صفين معاً
class a{
void w(){}
}
class b extends a{
void s(){}
}
class c extends b{
@Override
public void s(){}
@Override
public void w(){}
}
________________________________________________________________________
فيما يلي  .. نترك المجال مفتوحاً لأي جزء لم يتم التطرق إليه .. حتى يتكامل الموضوع بإذن الله ..
وسأبدأ بذكر بعض النقاط :
 
1-أحد أهم الاختلافات بين اللغتين قاعدة جافا الشهيرة : "write once, run anywhere"
حيث أن برامج جافا تنفذ بواسطة آلة جافا الافتراضية java virtual machine .. فأينما وجدت يمكنك تشغيل البرنامج ...
 
2-من المهم أن تعرف أن java بالأساس اعتمد مخترعها  James Gosling على لغة C++ ..وهذا يفسّر التشايه الكبير بينهما .. 
 
3-جافا تستعمل كلمة final بدل كلمة const لتعريف الثوابت ... 
 
4-استخدام template في جافا ..يكون بالشكل التالي 
public static < E > void printArray( E[] inputArray ){
}
ويكون الاستدعاء بمجرد تمرير الوسيط كما هو .. والمترجم يتكفل بكشف النوع ..على عكس ++C التي تجبرك على كتابة النوع .
 
5-استخدام حلقة for يتم على شكلين ... الأول مماثل لـ C أما الشكل الثاني Enhanced for-loop فنسخدمه لتوفير كتابة كود المرور على عناصر مصفوفة أو قائمة ..
for (int i = 0; i < N; i++) {
} 
 
 
for (String a : anyIterable) {
}
 
6- عند تعريف متحول في جسم الصف وإسناد قيمة له .. تعتبر هذه القيمة نهائية final اي ثابتة .. ولا يسمح بتغييره بعد ذلك .
class test{int a=0;}
 
هذا والله ولي التوفيق ... وله الحمد والشكر على توفيقه وكرمه ..
والسلام عليكم ورحمة الله وبركاته ..

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 27 أغسطس 2013 في 18:12

4
#2

قمت في الأسبوع الماضي باستخراج المزيد من الفروقات بين اللغتين .. ووجدت بعض ما يستحق الذكر ..


عندما نريد تمرير الوسطاء إلى دالة البناء الموجودة في الصف الأب .. عند استدعاء باني الابن !
في لغة ++C نكتب 
#include<cstdio>
class t{
public :
t(){
puts("Constuctor of t");
}
};
class f : public t{
public :
f(){
puts("Constuctor of f");
}
};
class g : public  t{
public :
g(): t(){
puts("Constuctor of g");
}
};
 
int main(){
t *a=new t();
t *b=new f();
t *c=new g();
return 0;
}
أما في جافا  فنستعمل الدالة super() وهي كلمة مفتاحية محجوزة .. يجب أن تكون أول تعلمية في الباني
مثال كامل 
public class testclasses {
public static void main(String[]args){
t a=new t();
t b=new f();
t c=new g();
}
}
class t{t(){System.out.println("Constuctor of t");}}
class f extends t{f(){System.out.println("Constuctor of f");}}
class g extends t{g(){
super();   System.out.println("Constuctor of g");}}
 
هذا الاختلاف جوهري .. وليس له مثيل في ++C  ... إن أي كائن هو وريث للصف الأب لكل الصفوف Object ..
وهذا الصف يحتوي توابع هامة مثل تابع المقارنة equals والتابع getClass على سبيل المثال ..
ويمكن لمترجم جافا أن يقوم بعملية تحويل بين أي نوع والنوع Object وهذا مفيد جدا في عملية التعميم Generic حيث يمكننا كتابة تابع وترك وسيطه من النوع Object وبذلك يمكنه قبول وسيط من أي نوع
 
public class Object$ {
public static void  main(String[]args){
p(0x36a2);
p("0x36a2");
p(0.362);
}
static void p(Object a){
System.out.println(a);
}
}
 
3-لا يوجد مفهوم الوسطاء الافتراضية في  Java كما أنه لا يوجد في C  ولكنه موجود في ++C .. حيث يمكنك اسناد قيمة افتراضية للمتحول في حال لم يتم تمرير هذا الوسيط له .
4-ذكرنا سابقاً أن عبارة switch لها استخدام مماثل لتلك في C  ولكن كما يبدو .. تم اضافة بعض المحسنات في النسخة 1.7من جافا 
بحيث صار يمكن عمل switch  على سلسلة نصية .. كما يلي :
String x="hello";
int y=0;
switch(x)
{
case "hello":y=1;break;
case "goodby":y=2;break;
}
أما في الإصدارات السابقة 1.6 وما قبل فلا يسمح إلا بint أو enum داخل قوسي الswitch تماما مثل C
5-تحدثنا عن عبارة for المحسنة والتي تقوم بعملية المرور على جميع عناصر مصفوفة او قائمة 
ولكن من المهم أن نذكر ان هذه العبارة وجدت في النسخ 1.5 فما فوق .. وغير موجوده قبل ذلك .
6-من الاختلافات الواضحة أن javaلا تضع فاصلة منقوطة عند نهاية تعريف الصف ولا تسمح بإنشاء أسماء مستعارة له كما لا يوجد شيء اسمه struct
7-حجم النمط int في C يعتمد على نظام التشغيل ... فيمكن أن يكون 16 أو 32 أو حتى 64 بت ..
أما في Java فهو 32 بت دوماً ...

أرجو من الاخوة التنبيه إلى أي خطأ .. والمشاركة في مزيد من الفروقات لإغناء الموضوع ..
والله ولي التوفيق
1
#3

سلّمك الله ونفعك ونفع بك، من أجمل مواضيعك وقد قضيت وقت ممتع في القراءة.

 

(+2).

" إن الله كتب الإحسان على كل شيء"

::

الإرادة ... تحقق السيادة.

#4

بارك الله فيك أخي A.S.Hack  .. أسعدني ردك ..
ولكن هناك بعض المغالطات في المقالات الثلاث فقد كنت أكتب المقالات تزامنا مع دراسة اللغة ... 
أحدى المغالطات كانت في وجوب وجود 

public static void main(String[]x){}

في جميع الأكواد  .. مع العلم أنها قد لا توجد في أي صف يرث من Applet  أو JFrame على سبيل المثال ... 

كما أن هناك بعض الأساليب الكائنية التوجه التي لم أشهدها من قبل .. ولم أجد فيها مجالا للمقارنة ... بل هي توجه جديد مدهش!

أحد الأكواد الذي حيرني في تركيبه النحوي ...!

 
Kfield =new JTextField("1",20);
Kfield.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
 
}
});

كما أنني أستدرك هنا وجود طريقة مدهشه في تعريف المصفوفات وإسنادها في آن واحد .. غير موجودة في ++C 

int x[]=new int []{1,2,3,4,5,6,7,8,9,10};

أخيراً وجدت أنه من المفيد مقارنة اللغتين باعتبار مخترعي Java استنسخو syntax ال++C ... ولكنه من الظلم المقارنة بين اللغتين ف++C هي الأفضل /الأسرع/ الأسهل في برمجة النظم والعتاد .. وJava هي أكثر محمولية وأماناً ..
أي أن المقارنة ظالمة فكلاهما يبرع في مجال مختلف عن الآخر ...
ختاماً  ما كان من خير وصواب فهو من توفيق الله تعالى ... وما كان غير ذلك فهو مني .. بارك الله في من صححه وصوّبه ..
والسلام  عليكم ورحمة الله وبركاته

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 10 سبتمبر 2013 في 22:37

#5
مصطفى 36a2 كتب:
أحد الأكواد الذي حيرني في تركيبه النحوي ...!
 
Kfield =new JTextField("1",20);
Kfield.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
 
}
});

 

الكود أعلاه مكتوب بطريقة تُسمى anonymous class  أو inner class وهي طريقة شائعة تعوّض الطريقة التالية:

myClass myObject = new myClass();

Kfield.addActionListener(myObject);

class myClass implemets ActionListener{

@override
public void actionPerformed(){}

}

أو بطريقة anonymous object هكذا:

Kfield.addActionListener(new myClass());

class myClass implemets ActionListener{

@override
public void actionPerformed(){}

}

تم تعديل هذه المشاركة بواسطة A.S Hack في 11 سبتمبر 2013 في 08:10

1

" إن الله كتب الإحسان على كل شيء"

::

الإرادة ... تحقق السيادة.

#6

تماماً ...
فكرة الinner class بحد ذاتها اختلاف لم أجد طريقة لعرضه .. فهو ميزة غريبة تغني عن جعل الصف الحالي يقوم بعمل implements لكل Listener عليه إضافته ...
جافا أكبر من ++C في مفاهيمها .. هذا ما بدأ بالتبلور عندي ...

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…