John Squirrels
مرحله
San Francisco

اصول OOP

در گروه منتشر شد
سلام! در درس امروز، در مورد اصول برنامه نویسی شی گرا صحبت خواهیم کرد. آیا تا به حال به این فکر کرده اید که چرا جاوا دقیقاً همانطور که هست طراحی شده است؟ منظورم اینه که شما کلاس ها رو اعلان می کنید و بر اساس کلاس ها شی می سازید، کلاس ها متد دارند و ... اما چرا ساختار زبان طوری است که برنامه ها از کلاس ها و آبجکت ها تشکیل شده اند نه چیز دیگری؟ چرا مفهوم «شیء» ابداع شد و در خط مقدم قرار گرفت؟ آیا همه زبان ها به این شکل طراحی شده اند؟ اگر نه، چه مزایایی به جاوا می دهد؟ همانطور که می بینید، سوالات زیادی وجود دارد :) بیایید سعی کنیم در درس امروز به هر یک از آنها پاسخ دهیم.

برنامه نویسی شی گرا (OOP) چیست؟

البته جاوا فقط برای سرگرمی از اشیا و کلاس ها تشکیل نشده است. آنها نه از هوس خالقان جاوا هستند و نه حتی اختراع آنها. بسیاری از زبان های دیگر بر اساس اشیاء وجود دارد. اولین چنین زبانی "Simula" نام داشت. در دهه 1960 در نروژ اختراع شد. علاوه بر این، مفاهیم "کلاس" و "روش" در سیمولا ظاهر شد. طبق استانداردهای توسعه نرم افزار، "Simula" یک زبان باستانی به نظر می رسد، اما هر کسی می تواند "شباهت خانوادگی" آن را با جاوا ببیند. اصول برنامه نویسی شی گرا - 1احتمالاً می توانید به راحتی کدهای نوشته شده به این زبان را بخوانید و به طور کلی توضیح دهید که چه کاری انجام می دهد :)
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» توسط Weekly-geekly گرفته شده است. همانطور که می بینید، جاوا چندان تفاوتی با پدربزرگ خود ندارد :) این به این دلیل است که ظاهر سیمولا تولد یک مفهوم جدید است: برنامه نویسی شی گرا. ویکی‌پدیا OOP را اینگونه تعریف می‌کند: «برنامه‌نویسی شی گرا (OOP) یک الگوی برنامه‌نویسی مبتنی بر مفهوم «اشیاء» است که می‌تواند شامل داده‌ها به شکل فیلدها (اغلب به عنوان ویژگی‌ها) و کد به شکل باشد. از رویه ها (اغلب به عنوان روش ها شناخته می شود). به نظر من این واقعا تعریف خوبی است. چندی پیش بود که شروع به یادگیری جاوا کردید، اما این تعریف احتمالاً حاوی کلماتی نیست که شما نمی دانید :) امروزه OOP رایج ترین متدولوژی برنامه نویسی است. علاوه بر جاوا، اصول OOP در بسیاری از زبان های محبوبی که ممکن است درباره آنها شنیده باشید استفاده می شود. به عنوان مثال، C++ (به طور فعال در توسعه بازی استفاده می شود)، Objective-C و Swift (برای نوشتن برنامه برای دستگاه های اپل استفاده می شود)، Python (محبوب ترین در یادگیری ماشینی)، PHP (یکی از محبوب ترین زبان های توسعه وب)، جاوا اسکریپت ( ساده تر است که بگوییم برای چه چیزی استفاده نمی شود) و بسیاری دیگر. بنابراین، اصول OOP چیست؟ ما با جزئیات به شما خواهیم گفت.

اصول OOP

اینها پایه و اساس بنیاد هستند. 4 ویژگی اصلی که با هم پارادایم برنامه نویسی شی گرا را تشکیل می دهند. درک آنها برای تبدیل شدن به یک برنامه نویس موفق ضروری است.

اصل 1. ارث

خبر خوب: شما قبلاً برخی از اصول OOP را می دانید! :) ما قبلاً چند بار در درس ها با وراثت مواجه شده ایم و توانستیم از آن استفاده کنیم. وراثت مکانیزمی است که به شما امکان می دهد یک کلاس جدید را بر اساس یک کلاس (والد) موجود توصیف کنید. با انجام این کار، کلاس جدید ویژگی ها و عملکرد کلاس والد را قرض می گیرد. وراثت برای چیست و چه مزایایی دارد؟ مهمتر از همه، استفاده مجدد از کد. فیلدها و متدهای اعلام شده در کلاس های والد را می توان در کلاس های فرعی استفاده کرد. اگر همه انواع خودروها دارای 10 فیلد مشترک و 5 روش یکسان هستند، فقط باید آنها را به کلاس والد Auto منتقل کنید . می توانید بدون هیچ مشکلی از آنها در کلاس های decendant استفاده کنید. مزایای ثابت: هم کمی (کد کمتر) و هم در نتیجه کیفی (کلاس ها بسیار ساده تر می شوند). علاوه بر این، وراثت بسیار انعطاف‌پذیر است - می‌توانید قابلیت نوشتن جداگانه‌ای را که فرزندان از دست داده‌اند (برخی فیلدها یا رفتارهایی که مختص یک کلاس خاص هستند) اضافه کنید. به طور کلی، مانند زندگی واقعی، همه ما تا حدودی شبیه والدین خود هستیم، اما به نوعی با آنها متفاوت هستیم :)

اصل 2. انتزاع

این یک اصل بسیار ساده است. انتزاع به معنای شناسایی اصلی ترین و مهم ترین ویژگی های چیزی است، در حالی که همزمان هر چیزی جزئی و ناچیز را دور می اندازد. احتیاجی به اختراع دوباره چرخ نیست. بیایید نمونه ای از یک درس قدیمی در مورد کلاس ها را به یاد بیاوریم. فرض کنید ما در حال ایجاد یک سیستم بایگانی برای کارمندان شرکت هستیم. برای ایجاد اشیاء "employee"، یک کلاس Employee نوشته ایم . چه ویژگی هایی برای توصیف آنها در سیستم پرونده شرکت مهم است؟ نام، تاریخ تولد، SSN و شناسه کارمند. اما بعید است برای این نوع رکورد به قد، رنگ چشم یا رنگ موی کارمند نیاز داشته باشیم. شرکت هیچ نیازی به چنین اطلاعاتی در مورد یک کارمند ندارد. بنابراین، در کلاس Employee ، متغیرهای زیر را اعلام می‌کنیم: String name ، int age ، int socialSecurityNumber و int staffId . و ما اطلاعات غیر ضروری مانند رنگ چشم را جمع آوری می کنیم. با این حال، اگر ما یک سیستم بایگانی برای یک آژانس مدلینگ بسازیم، وضعیت به طرز چشمگیری تغییر می کند. قد، رنگ چشم و رنگ موی یک مدل ویژگی های مهمی هستند، اما SSN او کاملاً برای ما بی ربط است. بنابراین، در کلاس Model ، متغیرهای زیر را ایجاد می کنیم: String height ، String hair ، string eyes .

اصل 3. کپسولاسیون

ما قبلاً به این موضوع برخورد کرده ایم. در جاوا، کپسوله سازی به معنای محدود کردن توانایی خواندن و تغییر داده ها است. همانطور که می بینید، این اصطلاح بر اساس کلمه "کپسول" است. ما از یک "کپسول" برای پنهان کردن برخی از داده های مهم استفاده می کنیم که نمی خواهیم دیگران تغییر کنند. در اینجا یک مثال ساده از زندگی واقعی است. شما یک نام و یک نام خانوادگی دارید. همه دوستان شما آنها را می شناسند. اما آنها توانایی تغییر نام یا نام خانوادگی شما را ندارند. ممکن است بگوییم که فرآیند انجام این کار توسط سیستم دادگاه "کاپسوله" شده است: شما می توانید نام خانوادگی خود را فقط از طریق منشی دادگاه تغییر دهید و فقط شما می توانید این کار را انجام دهید. سایر «کاربران» به نام و نام خانوادگی شما دسترسی «فقط خواندنی» دارند :) مثال گویا دیگر، پول نقدی است که در خانه نگهداری می شود. رها کردن آن در دید ساده در وسط اتاق ایده خوبی نیست. هر "کاربر" (فردی که به خانه شما می آید) می تواند مقدار پول شما را تغییر دهد، یعنی می تواند پول شما را بگیرد. بهتر است آن را در یک گاوصندوق محصور کنید. سپس دسترسی فقط برای شما و فقط با استفاده از یک کد خاص در دسترس خواهد بود. نمونه‌های آشکار کپسوله‌سازی که قبلاً با آن کار کرده‌اید، اصلاح‌کننده‌های دسترسی (خصوصی، عمومی، و غیره) و همچنین تنظیم‌کننده‌ها و دریافت‌کننده‌ها هستند. اگر فیلد سنی کلاس Cat را کپسوله نکنید ، هر کسی می‌تواند بنویسد:
Cat.age = -1000;
مکانیسم کپسوله‌سازی به ما امکان می‌دهد از میدان سنی با روش تنظیم‌کننده محافظت کنیم، جایی که می‌توانیم اطمینان حاصل کنیم که سن نمی‌تواند روی عدد منفی تنظیم شود.

اصل 4. چند شکلی

چند شکلی توانایی کار با چندین نوع است که گویی آنها یک نوع هستند. علاوه بر این، رفتار اشیا بسته به نوع آنها متفاوت خواهد بود. آیا این به نظر پیچیده است؟ بیایید همین الان آن را معنا کنیم. ساده ترین مثال را در نظر بگیرید: حیوانات. یک کلاس Animal با یک متد speak() و دو زیر کلاس ایجاد کنید - Cat و Dog .
public class Animal {

   public void speak() {

       System.out.println("Hello!");
   }
}

public class Dog extends Animal {

   @Override
   public void speak() {
       System.out.println ("Woof-woof!");
   }
}

public class Cat extends Animal {

   @Override
   public void speak() {
       System.out.println("Meow!");
   }
}
اکنون سعی می کنیم یک متغیر مرجع Animal را اعلام کنیم و یک شی Dog به آن اختصاص دهیم.
public class Main {

   public static void main(String[] args) {

       Animal dog = new Dog();
       dog.speak();
   }
}
به نظر شما چه روشی نامیده خواهد شد؟ Animal.speak() یا Dog.speak() ؟ متد در کلاس Dog نامیده می شود: Woof-woof! ما یک مرجع Animal ایجاد کردیم ، اما شی مانند یک سگ رفتار می کند . در صورت لزوم، می تواند مانند گربه، اسب یا حیوانات دیگر رفتار کند. نکته مهم این است که یک زیر کلاس خاص به متغیر مرجع عمومی Animal اختصاص دهیم . این منطقی است، زیرا همه سگ ها حیوان هستند. این همان چیزی است که وقتی گفتیم "رفتار اشیا بسته به نوع آنها متفاوت خواهد بود." اگر یک شی Cat ایجاد کنیم ...
public static void main(String[] args) {

   Animal cat = new Cat();
   cat.speak();
}
متد speak() "Meow ! " اما منظور ما از "توانایی کار با چندین نوع به گونه ای که گویی آنها یک نوع هستند" چیست؟ این نیز بسیار ساده است. بیایید تصور کنیم که در حال ایجاد یک آرایشگاه برای حیوانات هستیم. آرایشگاه ما باید بتواند هر حیوانی را تریم کند، بنابراین یک متد trim() با پارامتر Animal ایجاد می کنیم (حیوان در حال کوتاه کردن مو است).
public class AnimalBarbershop {

   public void trim(Animal animal) {

       System.out.println("The haircut is done!");
   }
}
و اکنون می توانیم اشیاء Cat و Dog را به متد trim() منتقل کنیم !
public static void main(String[] args) {

   Cat cat = new Cat();
   Dog dog = new Dog();

   AnimalBarbershop barbershop = new AnimalBarbershop();

   barbershop.trim(cat);
   barbershop.trim(dog);
}
و این مثال واضح است: کلاس AnimalBarbershop با انواع Cat و Dog طوری کار می کند که گویی آنها یک نوع هستند. در عین حال، گربه و سگ رفتارهای متفاوتی دارند: هر کدام متفاوت صحبت می کنند.

چرا به OOP نیاز داریم؟

چرا OOP حتی به عنوان یک مفهوم برنامه نویسی جدید بوجود آمد؟ برنامه نویسان ابزارهای کاربردی مانند زبان های رویه ای داشتند. چه چیزی آنها را به اختراع چیزی اساساً جدید ترغیب کرد؟ مهمتر از همه، پیچیدگی وظایفی که آنها با آن روبرو بودند. اگر 60 سال پیش وظیفه برنامه نویس چیزی شبیه "ارزیابی برخی عبارت های ریاضی" بود، اکنون می تواند چیزی شبیه به "اجرای 7 پایان مختلف برای بازی STALKER، بسته به ترکیبی از تصمیمات بازیکن در نقاط A، B، C، DE باشد. و F در بازی." همانطور که می بینید، وظایف به وضوح در دهه های گذشته پیچیده تر شده اند. و در نتیجه، انواع داده ها پیچیده تر شده اند. این یکی دیگر از دلایل ظاهر شدن OOP است. یک عبارت ریاضی را می توان به راحتی با استفاده از جملات اولیه معمولی ارزیابی کرد. در اینجا هیچ چیز مورد نیاز نیست. اما حتی بدون استفاده از کلاس‌های سفارشی، توصیف پایان‌های بازی دشوار است. همانطور که گفته شد، توصیف آن با استفاده از کلاس ها و اشیاء بسیار آسان است. بدیهی است که ما به چندین کلاس نیاز داریم: Game، Stalker، Ending، PlayerDecision، GameEvent و غیره. به عبارت دیگر، حتی بدون شروع حل مشکل، می توانیم به راحتی یک راه حل را در ذهن خود "طرح" کنیم. پیچیدگی روزافزون وظایف، برنامه نویسان را مجبور کرد که آنها را به بخش هایی تقسیم کنند. اما انجام این کار در برنامه نویسی رویه ای چندان آسان نبود. و اغلب یک برنامه مانند درختی بود با شاخه های زیادی که تمام مسیرهای اجرایی ممکن را نشان می داد. بسته به شرایط خاص، یکی از شاخه های برنامه یا دیگری اجرا می شد. برای برنامه های کوچک، این راحت بود، اما تقسیم یک مشکل بزرگ به بخش ها بسیار دشوار بود. این دلیل دیگری برای ظهور OOP بود. این پارادایم به برنامه نویسان این توانایی را داد که یک برنامه را به دسته ای از "ماژول ها" (کلاس ها) تقسیم کنند، که هر کدام بخشی از کار خود را انجام می دهند. با تعامل با یکدیگر، همه اشیا کار برنامه ما را انجام می دهند. علاوه بر این، می‌توانیم از کدهای خود در جای دیگری از برنامه استفاده مجدد کنیم که این نیز باعث صرفه‌جویی در زمان می‌شود.
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION