Salam! Heç düşünmüsünüzmü ki, Java niyə bu şəkildə tərtib edilib? O mənada ki, siz onların əsasında siniflər yaradırsınız - obyektlər, siniflərin metodları və s. Bəs niyə dilin strukturu elədir ki, proqramlar başqa bir şeydən yox, siniflərdən və obyektlərdən ibarətdir? Nə üçün “obyekt” anlayışı icad edildi və ön plana çıxdı? Bütün dillər bu şəkildə işləyirmi və yoxsa, Java-ya hansı üstünlükləri verir? Gördüyünüz kimi suallar çoxdur :) Gəlin bugünkü mühazirəmizdə onların hər birinə cavab verməyə çalışaq.

OOP prinsipləri:

  1. Miras
  2. Abstraksiya
  3. İnkapsulyasiya
  4. Polimorfizm

Obyekt yönümlü proqramlaşdırma (OOP) nədir

Təbii ki, Java müəyyən bir səbəbdən obyektlərdən və siniflərdən ibarətdir. Bu, onu yaradanların şıltaqlığı, hətta onların ixtirası da deyil. Obyektlərə əsaslanan bir çox başqa dillər var. İlk belə dil Simula adlanırdı və o, hələ 1960-cı illərdə Norveçdə icad edilmişdir. Digər şeylər arasında Simula “ sinf ” və “ metod ” anlayışlarını təqdim etdi . Obyekt yönümlü proqramlaşdırmanın prinsipləri - 2
Kristen Nygaard və Ole Johan Dahl - Simula yaradıcıları
Görünür ki, Simula proqramlaşdırma standartlarına görə qədim dildir, lakin onların Java ilə “ailə” əlaqəsi adi gözlə görünür. Çox güman ki, üzərində yazılan kodu rahatlıqla oxuyub onun nə etdiyini ümumi şəkildə izah edə bilərsiniz :)
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;
Kod nümunəsi Simula - 50 illik OOP məqaləsindən götürülmüşdür . Gördüyünüz kimi, Java və onun əcdadı bir-birindən o qədər də fərqlənmir :) Bu, Simula-nın meydana çıxması ilə yeni konsepsiyanın - obyekt yönümlü proqramlaşdırmanın doğulmasını qeyd etməsi ilə bağlıdır. Vikipediya OOP-un aşağıdakı tərifini verir: Obyekt yönümlü proqramlaşdırma (OOP) hər biri müəyyən bir sinfin nümunəsi olan və siniflər irsiyyət iyerarxiyasını təşkil edən obyektlər toplusu kimi proqramı təqdim etməyə əsaslanan proqramlaşdırma metodologiyasıdır. Məncə, çox uğurludur. Siz bu yaxınlarda Java dilini öyrənməyə başladınız, lakin orada sizə tanış olmayan sözlər demək olar ki, yoxdur :) Bu gün OOP ən çox yayılmış proqramlaşdırma metodologiyasıdır. Java ilə yanaşı, OOP prinsipləri haqqında eşitdiyiniz bir çox məşhur dillərdə istifadə olunur. Bunlar C++ (kompüter oyun tərtibatçıları tərəfindən fəal şəkildə istifadə olunur), Objective-C və Swift (onlar Apple cihazları üçün proqramlar yazır), Python (maşın öyrənməsində ən çox tələbat var), PHP (ən məşhur veb inkişaf dillərindən biri), JavaScript (daha sadə, onlarda nə etmədiklərini söyləyirlər) və bir çox başqaları. Əslində, OOP-un bu “prinsipləri” nədir? Sizə daha ətraflı danışaq.

OOP prinsipləri

Bu əsaslardır. Birlikdə obyekt yönümlü proqramlaşdırma paradiqmasını təşkil edən 4 əsas xüsusiyyət. Onları başa düşmək uğurlu proqramçı olmağın açarıdır. Obyekt yönümlü proqramlaşdırmanın prinsipləri - 3

Prinsip 1. Vərəsəlik

Yaxşı xəbər budur ki, siz OOP-un bəzi prinsipləri ilə artıq tanışsınız! :) Artıq bir neçə dəfə mühazirələrdə irsiyyətlə qarşılaşmışıq və onunla işləmək üçün vaxtımız olub. Varislik , mövcud (ana) sinfə əsaslanaraq yeni sinfi təsvir etməyə imkan verən mexanizmdir. Bu halda ana sinifin xassələri və funksionallığı yeni sinif tərəfindən götürülür. Vərəsəlik nə üçün lazımdır və onun hansı faydaları var? İlk növbədə kodun təkrar istifadəsi. Valideyn siniflərində təsvir edilən sahələr və üsullar nəsil siniflərdə istifadə edilə bilər. Bütün növ avtomobillərin 10 ümumi sahəsi və 5 eyni metodu varsa, sadəcə onları ana sinifə daxil etməlisiniz Auto. Onları heç bir problem olmadan nəsil siniflərində istifadə edə bilərsiniz. Möhkəm üstünlüklər: həm kəmiyyətcə (daha az kod), həm də nəticədə keyfiyyətcə (siniflər daha sadə olur). Eyni zamanda, miras mexanizmi çox çevikdir və nəsillərdə çatışmayan funksionallığı ayrıca əlavə edə bilərsiniz (bəzi sahələr və ya müəyyən bir sinfə xas davranış). Ümumiyyətlə, adi həyatda olduğu kimi: biz hamımız valideynlərimizə müəyyən mənada bənzəyirik, lakin bəzi mənalarda onlardan fərqliyik :)

Prinsip 2. Abstraksiya

Bu çox sadə bir prinsipdir. Abstraksiya obyektin əsas, ən əhəmiyyətli xüsusiyyətlərini vurğulamaq və əksinə - ikinci dərəcəli, əhəmiyyətsiz olanları atmaq deməkdir. Təkəri yenidən kəşf etməyək və dərslər haqqında köhnə mühazirədən bir nümunəni xatırlayaq. Tutaq ki, biz şirkət işçilərinin fayl şkafını yaradırıq. İşçi obyektlərini yaratmaq üçün bir sinif yazdıq Employee. Şirkət faylında onların təsviri üçün hansı xüsusiyyətlər vacibdir? Tam adı, doğum tarixi, sosial sığorta nömrəsi, vergi identifikasiya nömrəsi. Ancaq çətin ki, bu tip bir kartda onun boyu, gözləri və saç rənginə ehtiyacımız var. Şirkətə işçi haqqında bu məlumat lazım deyil. Buna görə də sinif üçün , və , Employeedəyişənlərini təyin edəcəyik və göz rəngi kimi bizim üçün lazımsız olan məlumatlardan imtina edib onu abstrakt edəcəyik. Amma bir agentlik üçün fotomodellər kataloqu yaratsaq, vəziyyət kəskin şəkildə dəyişir. Bir moda modelini təsvir etmək üçün boy, göz rəngi və saç rəngi bizim üçün çox vacibdir, lakin VÖEN nömrəsinə ehtiyac yoxdur. Buna görə də sinifdə , , dəyişənləri yaradırıq . String nameint ageint socialInsuranceNumberint taxNumberModelString heightString hairString eyes

Prinsip 3: İnkapsulyasiya

Biz bununla artıq qarşılaşmışıq. Java-da inkapsulyasiya məlumatlara girişi və onu dəyişdirmək imkanını məhdudlaşdırmaq deməkdir. Gördüyünüz kimi, "kapsula" sözünə əsaslanır. Bu "kapsulada" biz heç kimin dəyişməsini istəmədiyimiz bəzi vacib məlumatları gizlədirik. Həyatdan sadə bir nümunə. Adınız və soyadınız var. Onları tanıdığınız hər kəs tanıyır. Lakin onların ad və soyadınızı dəyişmək imkanı yoxdur. Bu proses, demək olar ki, pasport ofisində "inkapsullaşdırılıb": orada yalnız ad və soyadınızı dəyişə bilərsiniz və bunu yalnız siz edə bilərsiniz. Digər “istifadəçilər” sizin adınıza və soyadınıza yalnız oxumaq üçün giriş imkanına malikdir :) Başqa bir misal mənzilinizdəki puldur. Onları otağın ortasında açıq şəkildə buraxmaq yaxşı fikir deyil. İstənilən “istifadəçi” (evinizə gələn şəxs) pulunuzun nömrəsini dəyişə biləcək, yəni. onları götür. Onları seyfdə bağlamaq daha yaxşıdır. Yalnız siz və yalnız xüsusi kodla giriş əldə edəcəksiniz. Artıq işlədiyiniz inkapsulyasiyanın bariz nümunələri giriş modifikatorları ( private, publicvə s.) və getter-settersdir. Sinif sahəsi inkapsullaşdırılmayıbsa, hər kəs yaza bilər age:Cat
Cat.age = -1000;
İnkapsulyasiya mexanizmi bizə sahəni agetəyinedici metodla qorumağa imkan verir ki, bu zaman yaş mənfi rəqəm ola bilməz.

Prinsip 4. Polimorfizm

Polimorfizm bir neçə növə eyni tip kimi davranmaq qabiliyyətidir. Bu halda obyektlərin davranışı onların aid olduqları tipdən asılı olaraq fərqlənəcəkdir. Bir az mürəkkəb səslənir? İndi bunu anlayaq. Ən sadə misal götürək - heyvanlar. Gəlin Animaltək metodla - voice(), və onun iki nəslini - Catvə - ilə bir sinif yaradaq 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İndi bir keçid yaratmağa və ona obyekt təyin etməyə çalışaq Dog.
public class Main {

   public static void main(String[] args) {

       Animal dog = new Dog();
       dog.voice();
   }
}
Sizcə hansı üsul çağırılacaq? Animal.voice()yoxsa Dog.voice()? Sinif metodu belə adlandırılacaq Dog: Woof-woof! Biz istinad yaratdıq Animal, lakin obyekt kimi davranır Dog. Lazım gələrsə, o, pişik, at və ya başqa bir heyvan kimi davrana bilər. Əsas odur ki, Animalmüəyyən bir nəsil sinfinin obyektinə ümumi tipli bir istinad təyin etməkdir. Bu məntiqlidir, çünki bütün itlər heyvandır. “Obyektlər hansı tip olduqlarından asılı olaraq fərqli davranacaqlar” deyərkən bunu nəzərdə tuturduq. Bir obyekt yaratsaydıq Cat-
public static void main(String[] args) {

   Animal cat = new Cat();
   cat.voice();
}
metod voice()"Miyav!" “Bir neçə növlə eyni tipmiş kimi işləmək bacarığı” nə deməkdir? Bu da olduqca asandır. Təsəvvür edək ki, biz heyvanlar üçün kuaför salonu yaradırıq. Bizim saç salonumuz bütün heyvanları kəsə bilməlidir, ona görə də shear()parametrlə Animal- kəsəcəyimiz heyvanı olan bir üsul (“kəsmə”) yaradacağıq.
public class AnimalBarbershop {

   public void shear(Animal animal) {

       System.out.println("The haircut is ready!");
   }
}
İndi biz shearhəm obyektləri Cat, həm də obyektləri metoda ötürə bilərik 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);
}
Budur, aydın bir nümunə: sinif AnimalBarbershopnövlərlə işləyir, Catsanki Dogeyni tipdir. Eyni zamanda, onların Catfərqli Dogdavranışları var: səslərini fərqli şəkildə istifadə edirlər.

OOP-nin yaranmasının səbəbləri

Niyə bu yeni proqramlaşdırma konsepsiyası - OOP - hətta yarandı ? Proqramçıların işləyən alətləri var idi: məsələn, prosedur dilləri. Onları tamamilə yeni bir şey icad etməyə nə vadar etdi? Hər şeydən əvvəl, onların qarşısında duran vəzifələrin mürəkkəbliyi. Əgər 60 il əvvəl bir proqramçının tapşırığı “filan riyazi tənliyi hesabla” kimi görünürdüsə, indi bu, A, B, C, D oyun anlarında istifadəçinin hansı qərarlar verdiyindən asılı olaraq “STALKER oyunu üçün 7 fərqli sonluq həyata keçirin” kimi səslənə bilər. , E, F və bu həllərin birləşmələri." Gördüyünüz kimi, son onilliklər ərzində vəzifələr daha da mürəkkəbləşib. Bu o deməkdir ki, məlumat növləri daha mürəkkəbləşib. Bu, OOP-nin yaranmasının başqa bir səbəbidir. Tənlikli nümunə adi primitivlərdən istifadə etməklə asanlıqla həll edilə bilər, burada heç bir obyektə ehtiyac yoxdur. Ancaq icad etdiyiniz bəzi siniflərdən istifadə etmədən oyunun sonları ilə bağlı problemi təsvir etmək belə çətin olacaq. Ancaq eyni zamanda, onu siniflərdə və obyektlərdə təsvir etmək olduqca asandır: bizə açıq-aydın Oyun sinfi, Stalker sinfi, Bitiş sinfi, Oyunçunun Qərar sinfi, Oyun Anı sinfi və s. lazımdır. Yəni problemi həll etməyə başlamadan belə, onun həllinin “eskizlərini” beynimizdə asanlıqla təsəvvür edə bilərik. Problemlərin artan mürəkkəbliyi proqramçıları problemi hissələrə bölməyə məcbur etdi. Lakin prosedur proqramlaşdırmada bu o qədər də asan deyildi. Və çox vaxt proqram onun işləməsi üçün bütün mümkün variantları olan bir dəstə filialın "ağacı" idi. Müəyyən şərtlərdən asılı olaraq, proqram bu və ya digər filial boyunca icra olunurdu. Kiçik proqramlar üçün bu seçim əlverişli idi, lakin böyük bir işi hissələrə bölmək çox çətin idi. Bu ehtiyac OOP-nin yaranması üçün başqa bir səbəb oldu. Bu konsepsiya proqramçılara proqramı hər biri öz işini yerinə yetirən bir dəstə sinif “modullarına” bölmək imkanı verdi. Bir-biri ilə qarşılıqlı əlaqədə olan bütün obyektlər proqramımızın işini təşkil edir. Bundan əlavə, yazdığımız kodu proqramın başqa yerində təkrar istifadə etmək olar ki, bu da vaxta xeyli qənaət edir.