يكره مصممو Java تعقيد C++، لذا فإن Java موجزة للغاية، كما أن GC تجعل إدارة الذاكرة مريحة للغاية. يهتم C# بـ GC Java وتقنية الآلة الافتراضية، ويأمل في دمج العديد من لغات Microsoft الرئيسية في .NET. . لذلك، لغة C# ليست بسيطة أو حتى معقدة من حيث اللغة.
تختلف أيضًا أفكار التصميم بين اللغتين، فجافا هي لغة مجمعة ومفسرة، في حين أن لغة C# هي لغة مجمعة ومن ثم مجمعة وتشغيلها. جافا ليس لديها مفوضين، C# لديها مفوضين. تميل Java إلى استخدام Interface لتنفيذ وظائف المفوض، بينما في C#، يلعب Abstract Class دورًا أكبر من Interface.
تتبع Java قواعد التسمية الجملية، وتتبع لغة C# قواعد التسمية Pascal. ولكن الآن بدأ المزيد والمزيد من الأشخاص في Java في استخدام C#، وفي نفس الوقت يقومون بإحضار قواعد تسمية الجمل إلى C#، مما قد يجعل قراءة كود C# أكثر صعوبة. لماذا لم يتبع C# الجمل في المقام الأول؟ لا أرى أي شيء سيئ في اصطلاح تسمية الإبل.
1. اسم الفئة. هذا والطبقة الداخلية
في Java، غالبًا ما نرى استخدامًا مشابهًا لاسم الفئة. هذا هو مثيل الكائن الحالي. لماذا يظهر اسم الفئة أمامه؟ سيتم الخلط بين مبرمجي C # بسبب هذا.
في Java، يتم استخدام الفئات الداخلية في العديد من الأماكن، ويمكن حتى الوصول إلى أعضاء الطبقة الخارجية في الطبقة الداخلية. في هذا الوقت، عند استخدام هذا في الطبقة الداخلية، سينشأ السؤال حول من هو وما هو يعني هل هو مثيل الكائن الحالي للفئة الداخلية أم مثيل الكائن الحالي للفئة الخارجية؟
في Java، عن طريق إضافة اسم فئة الفئة الخارجية أمام هذا، فهذا يعني أنه سيتم استخدام مثيل الكائن الحالي للفئة الخارجية في الفئة الداخلية.
دعونا نلقي نظرة على مثال أدناه.
// تعريف الفئة الخارجية
الطبقة العامة OuterClass {
// تعريف الطبقة الداخلية
فئة خاصة InnerClass
{
// لا يوجد عضو معرف محدد في الفئة الداخلية. هنا يمكننا الوصول إلى الأعضاء في الفئة الخارجية.
public int getId(){ return OuterClass.this.id }
public void setId(int id) { OuterClass.this.id = id;}
// يتم تعريف عضو الاسم في الفئة الداخلية، ويمكن الوصول إلى الأعضاء في الفئة الداخلية مباشرة بشكل افتراضي، وهذا يصل إلى الأعضاء في الفئة الحالية.
اسم سلسلة خاصة؛
سلسلة عامة getName () {إرجاع هذا. الاسم؛}
// يمكنك إضافة اسم فئة داخلية أمام هذا
public void setName(String name) {InnerClass.this.name = name;}
// يمكن للطبقة الداخلية أيضًا الوصول إلى الأعضاء الذين يحملون نفس الاسم في الفئة الخارجية، ويجب إضافة اسم الفئة الخارجية.
سلسلة عامة getOuterName() {return OuterClass.this.name;}
public void setOuterName(String name) { OuterClass.this.name = name;}
@تجاوز
سلسلة عامة إلى سلسلة ()
{
إرجاع "المعرف:" + this.getId() + "، الاسم الداخلي: " + this.getName() + "، الاسم الخارجي: " + this.getOuterName();
}
}
// معرف العضو والاسم المحدد في الفئة الخارجية
معرف int الخاص؛
اسم سلسلة خاصة؛
InnerClass الداخلي الخاص؛
الفئة الخارجية العامة ()
{
this.innerInstance = new InnerClass();
this.innerInstance.setId(20);
this.innerInstance.setName("توم");
this.innerInstance.setOuterName("أليس");
}
سلسلة عامة إلى سلسلة ()
{
إرجاع this.innerInstance.toString();
}
}
في C#، يتم تقسيم الفئات إلى فئات متداخلة وفئات غير متداخلة. الأول هو فئة معلنة داخل أنواع البيانات الأخرى. الأخير عبارة عن فئة محددة مباشرة في مساحة اسم معينة. نادرًا ما يتم تعريف الفئات المتداخلة في لغة C#.
تسمح الفئات غير المضمنة فقط باستخدام عناصر التحكم في الوصول العامة والداخلية، بينما تسمح الفئات المضمنة باستخدام جميع أحرف التحكم في الوصول الخمسة، الخاصة والمحمية والمحمية الداخلية والعامة والداخلية. يمكن للفئات الداخلية أيضًا الوصول إلى جميع أساليب الفئة الخارجية، بما في ذلك أساليب المثيل والأساليب الخاصة، ولكنها تحتاج إلى تمرير مثيل للفئة الخارجية بشكل صريح.
يمكن للفئات الداخلية في C# استخدام الأنواع والأساليب الثابتة التي تحددها الفئات الخارجية، ولكن لا يمكنها استخدام أساليب المثيل للفئات الخارجية بشكل مباشر، لذلك لا توجد مشكلة أعلاه.
في C#، تعمل الفئة الخارجية كمساحة اسم للفئة الداخلية طالما أن التحكم في الوصول يسمح بذلك، يمكنك استخدام الطريقة التالية لإنشاء مثيل لكائن الفئة الداخلية.
OuterClass.InnerClass obj = new OuterClass.InnerClass(); ليس لهذا المثيل علاقة مباشرة مع أي مثيل للفئة الخارجية. على غرار الطبقات الداخلية الثابتة في جافا.
2. اسم الفئة.الطبقة والنوع
في Java، غالبًا ما نرى استخدام class name.class. هذا الاستخدام يعادل typeof (اسم الفئة) في C#، والذي يُستخدم للحصول على مرجع مثيل كائن النوع.
في Java، كل فئة لها كائن فئة مطابق. عند كتابة فئة وتجميعها، يتم إنشاء كائن فئة في ملف .class الذي تم إنشاؤه لتمثيل معلومات النوع الخاصة بالفئة. ثلاث طرق للحصول على مثيلات الفئة:
احصل على مثيل فئة الكائن عن طريق استدعاء أسلوب getClass() لمثيل الكائن.
استخدم الطريقة الثابتة forName() of Class للحصول على مثيل Class باستخدام اسم الفئة. تقوم Class.forName(xxx.xx.xx) بإرجاع فئة، وتتمثل مهمتها في مطالبة JVM بالعثور على الفئة المحددة وتحميلها، مما يعني أن JVM سيقوم بتنفيذ مقطع التعليمات البرمجية الثابت للفئة.
احصل على مثيل الفئة باستخدام اسم الفئة .calss بالنسبة لفئات التغليف لأنواع البيانات الأساسية، يمكنك أيضًا استخدام .TYPE للحصول على مثيل الفئة لنوع البيانات الأساسي المقابل.
تعد طريقة الحصول على مثيل لكائن كتابة في C# أبسط وأكثر وضوحًا.
يتم الحصول عليها عن طريق استدعاء طريقة GetType() لمثيل البيانات. يتم توريث هذه الطريقة من الكائن، لذا فإن أي كائن في C# له طريقة GetType()، x.GetType()، حيث x هو اسم المتغير.
x في typeof(x) يجب أن يكون اسم فئة محددًا، واسم نوع، وما إلى ذلك، ولا يمكن أن يكون اسمًا متغيرًا.
من خلال الطريقة الثابتة System.Type.GetType() لـ System.Type.
3. فئة مجهولة
في Java، يتم أيضًا استخدام الفئات المجهولة في كثير من الأحيان. على سبيل المثال، في Android، عند تنفيذ مراقبة الأزرار، غالبًا ما ترى رمزًا مثل هذا.
@تجاوز
الفراغ العام عند النقر (عرض arg0) {
Intentint = new Intent( MainActivity.this, ActivityFrameLayout.class);
setTitle("FrameLayout");
بداية النشاط (القصد)؛
}
};
هنا، OnClickListenter هو في الواقع واجهة، هل يمكن استخدام الواجهة لإنشاء مثيلات الكائن؟ بالطبع لا.
لذلك، تقوم Java تلقائيًا بإنشاء فئة مجهولة تنفذ الواجهة هنا. ما نقوم بإنشائه هو في الواقع مثيل كائن لهذه الفئة المجهولة.
وميزة ذلك هي أننا لا نحتاج إلى تحديد فئة يتم استخدامها مرة واحدة فقط، ثم إنشاء مثيلات كائن من خلال هذه الفئة، مما يبسط تطوير البرنامج.
على سبيل المثال، لدينا الواجهة التالية.
example.onClick(); في لغة C#، لن نستخدم هذا النموذج على الإطلاق من خلال التفويض، ويمكن تحقيق نفس الوظيفة بكل بساطة.
لاحظ أنه لا يوجد مندوبين في Java.
إذا قمنا بطباعة نوع هذا المثيل، فسترى النوع الفعلي لهذه الفئة المجهولة.
يجب أن يكون مفهوم السمات مألوفًا للجميع. يمكن لوظائف أعضاء الفصل الوصول بحرية إلى أي عضو سمات في هذا الفصل. ومع ذلك، يعد الوصول إلى خصائص فئة أخرى من فئة واحدة أكثر صعوبة، لذلك نستخدم في كثير من الأحيان أساليب Getxxx وSetxxx، والتي تبدو غير طبيعية للغاية، على سبيل المثال، في Java أو C++، يكون الكود كما يلي:
ومع ذلك، في C#، يتم "منسوب" هذه الأساليب. نفس الكود في لغة C# يصبح:
foo.size++;
label.font.bold = true;
كما ترون، من الواضح أن لغة C# أسهل في القراءة والفهم. يمكننا أيضًا أن نرى موقفًا مشابهًا من الكود الفرعي الخاص بـ "طريقة الخاصية" هذه:
جافا/سي++:
ج#:
من أجل تمييز هذا النوع من الأساليب المنسوبة عن أعضاء السمات في الفصل، يُطلق على أعضاء السمات اسم "الحقول" في لغة C#، وتصبح "السمة" الاسم الخاص لهذه "الطريقة المنسوبة". بالمناسبة، في الواقع، هذا النوع من أساليب السمات غالبًا ما يتم مواجهته في VB وDELPHI، ويسمى أيضًا في VB بالسمة. بالإضافة إلى ذلك، يجب أن يظهر Get وSet في أزواج في C#، لا يمكن أن تحتوي الخاصية على Get فقط بدون Set (في Java وC++، يمكن أن تحتوي فقط على Get أو Set فقط). إذا كنت تريد تعديل سمة معينة، فسوف تنتبه إلى طرق Get وSet في نفس الوقت وتعديلها في نفس الوقت، ولن تغير هذا وتنسى ذلك.
5. آلية فهرسة الكائنات (المفهرس)
تم تقديم آلية فهرسة الكائنات في لغة C#. لتوضيح الأمر بشكل أكثر وضوحًا، فهرس الكائنات هو في الواقع مصفوفة من الكائنات. دعونا نتحدث عن ذلك فيما يتعلق بالخصائص الموجودة في القسم السابق، تحتاج الخصائص إلى إخفاء أساليب Get وSet، ولكن في آلية الفهرس، يتم الكشف عن أساليب Get أو Set لكل كائن. على سبيل المثال، يوضح المثال التالي هذه النقطة بشكل أكثر وضوحًا. ما ورد أعلاه يقدم الاختلافات بين C# وJava
القصص [الفهرس] = القيمة؛
}
}
}
...
}
ما ورد أعلاه يوضح الاختلافات بين C# وJAVA وآمل أن يكون من المفيد لك فهم C# وJAVA.