مرحبًا! هل تساءلت يومًا لماذا تم تصميم Java بهذه الطريقة؟ بمعنى أنك تقوم بإنشاء فئات بناءً عليها - الكائنات، والفئات لها طرق، وما إلى ذلك. ولكن لماذا تكون بنية اللغة بحيث تتكون البرامج من فئات وأشياء وليس من شيء آخر؟ لماذا تم اختراع مفهوم "الشيء" ووضعه في المقدمة؟ هل تعمل جميع اللغات بهذه الطريقة، وإذا لم يكن الأمر كذلك، ما هي الفوائد التي تقدمها جافا؟ كما ترون، هناك الكثير من الأسئلة :) دعونا نحاول الإجابة على كل واحد منهم في محاضرة اليوم.
كريستين نيجارد وأولي يوهان دال - مبتكرو Simula
يبدو أن لغة Simula هي لغة قديمة وفقًا لمعايير البرمجة، لكن ارتباطها "العائلي" بجافا مرئي للعين المجردة. على الأرجح، يمكنك بسهولة قراءة الكود المكتوب عليه وشرح ما يفعله بشكل عام :)
مبادئ OOP:
ما هي البرمجة الشيئية (OOP)
بالطبع، تتكون Java من كائنات وفئات لسبب ما. هذه ليست نزوة من المبدعين، أو حتى اختراعهم. هناك العديد من اللغات الأخرى التي تعتمد على الكائنات. أول لغة من هذا القبيل كانت تسمى سيمولا، وتم اختراعها في ستينيات القرن العشرين في النرويج. من بين أمور أخرى، قدم سيمولا مفاهيم " الطبقة " و" الطريقة ".Begin
Class Rectangle (Width, Height); Real Width, Height;
Begin
Real Area, Perimeter;
Procedure Update;
Begin
Area := Width * Height;
OutText("Rectangle is updating, Area = "); OutFix(Area,2,8); OutImage;
Perimeter := 2*(Width + Height);
OutText("Rectangle is updating, Perimeter = "); OutFix(Perimeter,2,8); OutImage;
End of Update;
Update;
OutText("Rectangle created: "); OutFix(Width,2,6);
OutFix(Height,2,6); OutImage;
End of Rectangle;
Rectangle Class ColouredRectangle (Color); Text Color;
Begin
OutText("ColouredRectangle created, color = "); OutText(Color);
OutImage;
End of ColouredRectangle;
Ref(Rectangle) Cr;
Cr :- New ColouredRectangle(10, 20, "Green");
End;
مثال الكود مأخوذ من المقالة Simula - 50 Years of OOP . كما ترون، جافا وسلفها لا يختلفان كثيرًا عن بعضهما البعض :) ويرجع ذلك إلى حقيقة أن ظهور Simula يمثل ولادة مفهوم جديد - البرمجة الموجهة للكائنات. تقدم ويكيبيديا التعريف التالي لـ OOP: البرمجة الشيئية (OOP) هي منهجية برمجة تعتمد على تمثيل البرنامج كمجموعة من الكائنات، كل منها عبارة عن مثيل لفئة معينة، وتشكل الفئات تسلسلاً هرميًا للوراثة. وهو، في رأيي، ناجح للغاية. لقد بدأت مؤخرًا في تعلم Java، ولكن لا يوجد أي كلمات غير مألوفة بالنسبة لك :) اليوم، OOP هي منهجية البرمجة الأكثر شيوعًا. إلى جانب Java، يتم استخدام مبادئ OOP في العديد من اللغات الشائعة التي ربما سمعت عنها. هذه هي لغة C++ (يتم استخدامها بشكل نشط من قبل مطوري ألعاب الكمبيوتر)، وObjective-C وSwift (يكتبون برامج لأجهزة Apple)، وPython (الأكثر طلبًا في التعلم الآلي)، وPHP (إحدى لغات تطوير الويب الأكثر شيوعًا)، جافا سكريبت (أسهل قول ما لا يفعلونه بها) وغيرها الكثير. في الواقع، ما هي "مبادئ" OOP؟ دعنا نخبرك بمزيد من التفاصيل.
مبادئ OOP
هذه هي الأساسيات. 4 ميزات رئيسية تشكل معًا نموذج البرمجة الشيئية. فهمهم هو المفتاح لتصبح مبرمجًا ناجحًا.المبدأ 1. الميراث
والخبر السار هو أنك على دراية ببعض مبادئ OOP! :) لقد واجهنا بالفعل موضوع الميراث عدة مرات في المحاضرات، وكان لدينا الوقت للعمل معه. الميراث هو آلية تسمح لك بوصف فئة جديدة بناءً على فئة (أصلية) موجودة. في هذه الحالة، يتم استعارة خصائص ووظائف الفئة الأصلية بواسطة الفئة الجديدة. لماذا الميراث ضروري وما هي الفوائد التي يوفرها؟ أولًا، إعادة استخدام الكود. يمكن استخدام الحقول والأساليب الموضحة في الفئات الأصلية في الفئات التابعة. إذا كانت جميع أنواع السيارات تحتوي على 10 حقول مشتركة و5 طرق متطابقة، فأنت بحاجة فقط إلى وضعها في الفئة الأصلAuto
. يمكنك استخدامها في الفئات التابعة دون أي مشاكل. المزايا الصلبة: سواء من الناحية الكمية (رمز أقل)، ونتيجة لذلك، من الناحية النوعية (تصبح الفصول الدراسية أبسط بكثير). في الوقت نفسه، تكون آلية الميراث مرنة للغاية، ويمكنك إضافة الوظائف المفقودة في الأحفاد بشكل منفصل (بعض الحقول أو السلوك الخاص بفئة معينة). بشكل عام، كما هو الحال في الحياة العادية: نحن جميعًا نشبه آباءنا في بعض النواحي، ولكننا نختلف عنهم في بعض النواحي :)
المبدأ 2. التجريد
هذا مبدأ بسيط للغاية. التجريد يعني تسليط الضوء على الخصائص الرئيسية والأكثر أهمية للكائن والعكس - التخلص من الخصائص الثانوية غير المهمة. دعونا لا نعيد اختراع العجلة ونتذكر مثالاً من محاضرة قديمة عن الفصول الدراسية. لنفترض أننا نقوم بإنشاء خزانة ملفات لموظفي الشركة. لإنشاء كائنات الموظفين، كتبنا فئةEmployee
. ما هي الخصائص المهمة لوصفها في ملف الشركة؟ الاسم الكامل، تاريخ الميلاد، رقم الضمان الاجتماعي، رقم التعريف الضريبي. لكن من غير المرجح أن نحتاج إلى طوله ولون عينيه وشعره في بطاقة من هذا النوع. ولا تحتاج الشركة إلى هذه المعلومات عن الموظف. لذلك، بالنسبة للفصل ، Employee
سنقوم بتعيين المتغيرات و و و، وسنتخلى عن المعلومات غير الضرورية بالنسبة لنا، مثل لون العين، ونقوم بتجريدها. ولكن إذا قمنا بإنشاء كتالوج لنماذج الصور لوكالة ما، فإن الوضع يتغير بشكل كبير. لوصف عارضة أزياء، يعد الطول ولون العين ولون الشعر أمرًا مهمًا جدًا بالنسبة لنا، ولكن ليس هناك حاجة إلى رقم التعريف الضريبي. لذلك، في الفصل نقوم بإنشاء المتغيرات ، .String name
int age
int socialInsuranceNumber
int taxNumber
Model
String height
String hair
String eyes
المبدأ 3: التغليف
لقد واجهناها بالفعل. التغليف في Java يعني تقييد الوصول إلى البيانات والقدرة على تغييرها. كما ترون، فإنه يقوم على كلمة "كبسولة". في هذه "الكبسولة" نخفي لنا بعض البيانات المهمة التي لا نريد أن يغيرها أحد. مثال بسيط من الحياة . لديك الاسم الأول والأخير. كل من تعرفه يعرفهم. لكن ليس لديهم إمكانية الوصول لتغيير اسمك الأول والأخير. يمكن القول أن هذه العملية "مغلفة" في مكتب الجوازات: يمكنك فقط تغيير اسمك الأول والأخير هناك، ولا يمكن لأحد سواك القيام بذلك. يتمتع "المستخدمون" الآخرون بحق الوصول للقراءة فقط إلى اسمك الأول واسم العائلة :) مثال آخر هو الأموال الموجودة في شقتك. إن تركهم على مرأى من الجميع في منتصف الغرفة ليس فكرة جيدة. سيتمكن أي "مستخدم" (الشخص الذي يأتي إلى منزلك) من تغيير رقم أموالك، أي. أقلهم. من الأفضل تغليفها في خزنة. لن يتمكن أحد سواك من الوصول إلا باستخدام رمز خاص. من الأمثلة الواضحة على التغليف الذي عملت معه بالفعل هي معدّلات الوصول (private
وما public
إلى ذلك) وأدوات ضبط الحروف. إذا لم يتم تغليف حقل age
الفئة ، يمكن لأي شخص أن يكتب:Cat
Cat.age = -1000;
وتسمح لنا آلية التغليف بحماية الحقل age
بطريقة ضبط، حيث يمكننا التحقق من أن العمر لا يمكن أن يكون رقمًا سالبًا.
المبدأ 4. تعدد الأشكال
تعدد الأشكال هو القدرة على التعامل مع أنواع متعددة كما لو كانت نفس النوع. في هذه الحالة، سيختلف سلوك الكائنات حسب النوع الذي تنتمي إليه. يبدو معقدا بعض الشيء؟ دعونا معرفة ذلك الآن. لنأخذ أبسط مثال - الحيوانات. لنقم بإنشاء فئةAnimal
بأسلوب واحد - voice()
واثنين من أحفادها - Cat
و Dog
.
public class Animal {
public void voice() {
System.out.println("Voice!");
}
}
public class Dog extends Animal {
@Override
public void voice() {
System.out.println("Bow-wow!");
}
}
public class Cat extends Animal {
@Override
public void voice() {
System.out.println("Meow!");
}
}
الآن دعونا نحاول إنشاء رابط Animal
وتعيين كائن له Dog
.
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.voice();
}
}
ما هي الطريقة التي تعتقد أنه سيتم استدعاؤها؟ Animal.voice()
أو Dog.voice()
؟ سيتم استدعاء طريقة الفصل Dog
: Woof-woof! لقد أنشأنا مرجعًا Animal
، لكن الكائن يتصرف مثل Dog
. إذا لزم الأمر، يمكنه أن يتصرف مثل قطة أو حصان أو حيوان آخر. الشيء الرئيسي هو تعيين مرجع من النوع العام Animal
لكائن من فئة سليل محددة. وهذا أمر منطقي، لأن كل الكلاب حيوانات. وهذا ما قصدناه عندما قلنا "الأشياء سوف تتصرف بشكل مختلف اعتمادًا على نوعها". إذا أردنا إنشاء كائن Cat
-
public static void main(String[] args) {
Animal cat = new Cat();
cat.voice();
}
voice()
ستخرج الطريقة "مواء!" ماذا تعني عبارة "القدرة على العمل مع عدة أنواع كما لو كانت نفس النوع"؟ وهذا أيضًا سهل جدًا. لنتخيل أننا نقوم بإنشاء صالون لتصفيف شعر الحيوانات. يجب أن يكون صالون تصفيف الشعر الخاص بنا قادرًا على قص جميع الحيوانات، لذلك سنقوم بإنشاء طريقة shear()
("القص") مع معلمة Animal
- الحيوان الذي سنقطعه.
public class AnimalBarbershop {
public void shear(Animal animal) {
System.out.println("The haircut is ready!");
}
}
والآن يمكننا تمرير shear
كل من الكائنات Cat
والكائنات إلى الطريقة Dog
!
public static void main(String[] args) {
Cat cat = new Cat();
Dog dog = new Dog();
AnimalBarbershop barbershop = new AnimalBarbershop();
barbershop.shear(cat);
barbershop.shear(dog);
}
فيما يلي مثال واضح: يعمل الفصل AnimalBarbershop
مع الأنواع Cat
كما Dog
لو كانت من نفس النوع. وفي الوقت نفسه، لديهم سلوك Cat
مختلف Dog
: فهم يستخدمون أصواتهم بشكل مختلف.
GO TO FULL VERSION