Saturday, 28 January 2017

ობიეკტზე ორიენტირებული პროგრამირება. ნაწილი 2. აბსტრაქცია, პოლიმორფიზმი, ენკაპსულაცია

                                                                                           


                                                                            Abstraction

კლასი რომლის დეკლალირებაც ხდება საკვანძო სიტყვით abstract გახლავთ აბსტრაკტული კლასი, მას შეიძლება ექნეს როგორც აბსტრაკტული ისე კონკრეტული მეთოდები, კონკრეტული მეთოდი არის ვირტუალი, ანუ სტანდარტული მეთოდი. იდეა რომელიც ამ საკვანძო სიტყვის უკან დგას არის: ანახო მომხმარებელს ის რაც ჭრიდება და დამალო ფუნქცია. მაგალითისთვის მესიჯის გაგზავნა, ან ფოსტის გაგზავნა, ყველამ ვიცით რო გაგზავნამდე უნდა მიუთითოთ ადრესატი, შევიყვანოთ ტექსტი და დავაჭიროთ გაგზავნის ღილაკს, მაგრამ არავინ იცის ამის უკან რა დგას და როგორ მუშაობს ესა თუ ის ოპერაცია. შემოკლებით: აბსტრაქციის მეშვეობით ვიცით რას აკეთებს ობიეკტი მაგრამ არ ვიცით როგორ!

აბსტრაკტული მეთოდი გახლავთ მეთოდი ტანის გარეშე. abstract void run(); რომლის მოქმედებაც სრულდება ;-თი და არა ფრჩხილებით. კლასი რომელშიც დეკლალირებულია ასბტრაკტული მეთოდი აუცილებლად უნდა იყოს ასბტრაკტული. შეუძლებელია აბსტრაკტული კლასის ინსტანცირება, ანუ მისგან ობიეკტი არ იქმნება, რომ გამოიყენოთ აბსტრაკტული კლასი და შექმნათ მისგან ობიეკტი უნდა მოახდინოთ მისი მემკვიდრეობით გადაცემა სხვა კლასზე, რომელიც აუცილებლად მიიღებს აბსტრაკტული კლასიდან ყველა აბსტრაკტულ მეთოდს, (თუ არ მოახდინეთ ყველა აბსტრაკტული მეთოდის გამოყენება კლასის მარკირება უნდა მაოხდინოთ როგორც აბსტრაკტულის, წინააღმდეგ შემთხვევაში პროგრამას ვერ გაუშვებთ. აბსტრაკტული მეთოდების ინსტანცირება დ გადაწერა ვალდებულებას წარმოადგენს) რის შემდგომაც შექმნით ობიეკტს. 

გამოყენების წესები :

1. კლასი რომ ვაქციოთ აბსტრაკტულად მის სახელს უნდა დავამატოთ საკვანძო სიტყვა abstract
2. აბსტრაკტულ კლას შესაძლებელია ექნეს აბსტრაკტული და ჩვეულებრივი მეთოდები
3. აბსტრაკტულ კლას ვერ მიანიჭებთ final მოდიფიკატორს
4. აბსტრაკტულ კლასში არ არის აუცილებელი იქონიოთ ასბტრაკტული მეთოდი, თუმცა პირიქით აბსტრაკტული მეთოდი აუცილებელია იყოს აბსტრაკტულ კლასში
5. აბსტრაკტული კლასის ინსტანცირება არ შეიძლება(მისგან ვერ შექმნით ობიეკტს) თუმცა შეიძლება მემკვიდრეობით გადაცემა, 
6. აუცილებელია ყველა აბსტრაკტული მეთოდის იმპლემენტირება ქვე კლასში. გადაწერა (Override)
7. აბსტრაკტულ მეთოდს არ აქვს ტანი
8. აბსტრაკტულ კლას შეუძლია მემკვიდრეობით აიღოს ინფორმაცია მხოლოდ ერთი კლასიდან ან მხოლოდ ერთი აბტრაკტული კლასიდან
9. აბსტრაკტულ კლას შეუძლია მემკვიდრეობით გადაცეს ინფორმაცია მხოლოდ ერთ კლას ან აბსტრაკტულ კლასს
10. კლას შეუძლია მემკვიდრე იყოს მხოლოდ ერთი აბსტრაკტული კლასის
11. აბსტრაკტული მეთოდს შეუძლია იყოს public და protected მოდიფიკატორით, სხვა მოდიფიკატორებს ვერ მიანიჭებთ რადგან private, final და static მოდიფიკატორის მინიჭების შემთხვევაში ვერ მოახერხებთ მის იმპლემენტირებას ქვე კლასში, რაც აუცილებელია
12. აბსტრაკტულ კლასში შესაძლებელია იქონიოთ ნებისმიერი მხედველობის ცვლადი ან მეთოდი. 
13. აბსტრაკტულ კლას შეუძლია ექნეს, კონსტრუკტორი და ყველა სახეობის მეთოდი მათ შორის main მეთოდიც

დეკლალირების მაგალითი:


აბსტრაკტული კლასი არის public ან default მოდიფიკატორით, ის ვერ იქნება protected ან private, რადგან ის სუპერ კლასია და მისი ინსტანცირება სხვა კლასის მეშვეობით აუცილებლად უნდა მოხდეს.

აბსტრაკტული მეთოდის დეკლალირების მაგალითი:
აბსტრაკტული კლასის მემკვიდრეობით გადაცემა:

მისგან ვერ შევქმენით ობიეკტი, მაგრამ კლას პერსონისგან შეიქმნა მარტივად რის შემდგომაც მოვახდინეთ ყველაფრის ინსტანცირება ქვე კლასში, აბსტრაკტული მეთოდის იმპლემენტირებასთან ერთად. რომ არ მოგვეხდინა აბსტრაკტული მეთოდის იმპლემენტაცია მაშინ ჯავა პროგრამას არ გაუშვებდა ან თვითონ პერსონის კლასი უნდა მოგვენიშნა აბსტრაკტულად. ამის შემდგომ ნებისმიერ კლასი რომელიც მოახდენს აბსტრაკტული კლასისგან ინფორმაციის მიღებას აუცილებლად გამოიყენებს salary() მეთოდს, ბანკი, კომპანია, მაღაზია და ა.შ


ეს გახლავთ ძირითადი ბირთვი ასბტრაქციის ჯავაში, აბსტრაკტული კლასი რომელისგან ობიეკტი არ იქნება და აბსტრაკტული მეთოდი რომელიც აუცილებლად უნდა გამოიყენოთ. დამატებით წესებს მაგალითებზე ნახავთ. 

როდის გამოვიყენოთ აბსტრაქცია:

1. როდესაც ხედავთ რომ რამოდენიმე კლას გაჩნიათ საბაზისო ერთობა

2. როდესაც სურვილი არ გაქვთ სტატიკური და ფინალური ცვლადების გამოყენების. რაც თავის მხრივ საშუალებას მოგცემთ ინსტანცირებულ კლასებში მოახდინოთ ცვლილებები. 



ალბათ გიკვირთ და ვერ ხვდებით რა შუაშია ეს ყველაფერი აბსტრაქციასთან, მაგრამ მიხვდებით როცა ინტერფეისებს გაეცნობით. აბსტრაკტულ კლას იყენებთ მაშინ როცა გაქვთ სურვილი ნაწილობრივი აბსტრაქციის, თუმცა არსებობს 100 % აბსტრაქცია და მას ინტერფეისი ქვია. 

                                                                                       Interface

ინტერფეისი ჯავაში არის ხელსაწყო რომლის მეშვეობითაც ვაღწევთ სრულ აბსტრაქციას, მსგავსად აბტრაკტული კლასისა მისგანაც ვერ შექმნით ობიეკტს, ის გამოიყურება როგორც კლასი მაგრამ სინამდვილეში ეს ასე არ არის, მისი დეკლალირებისთვის არ ვიყენებთ საკვანძო სიტყვა class-ს. მას შეუძლია იქონიოს ცვალდები და მეთოდები ისევე როგორც კლას მაგრამ ერთი თავისებურებით, ინტერფეისი სტანდარტულად არის აბსტრაკტული, ყველა მეთოდი ინტერფეისში სტანდარტულად გახლავთ აბსტრაკტული და ცვლადები public, static & final მხოლოდ. მსგავსად აბსტრაკტული კლასისა როცა გვსურს ინტერფეისის გამოყენება სავალდებულო გახლავთ მისი ყველა მეთოდის გამოყენება რომ პროგრამა გაუშვათ ან წინააღმდეგ შემთხვევაში კლასი უნდა მოინიშნოს როგორც ასბტრაკტული. დეკლარირების მაგალითი:

                         public interface MyDemo{

                                 }

როგორც ხედავთ კლასი არსად არ არის ნახსენები, ინტერფეისის ქონა შესაძლებელია მხოლოდ ორი მოდიფიკატორით, public ან


Default.

მეთოდების დეკლალირება ხდება ისევე როგორც აბსტრაკტულ კლასში. მაგრამ განსხვავებით აბსტრაკტული კლასისა ინტერფეისიდან იმფორმაცია მემკვიდრეობით არ გადაიცემა, არამედ იმპლემენტაციით. ნახეთ მაგალითი:



ანუ თუ სურვილი გვაქ რომ მოვახდინოთ ინფორმაციის აღება ინტერფეისიდან ვიყენებთ საკვანძო სიტყვა implements. სურათზე ისრებით მითითებულია მაჩვენებლები, ინტერფეისის მაჩვენებელია I და კლასის C. მოკლე შესავალი ამით დასრულდა, ახლა კი დეტალურად გავეცნოთ თემას. 

წესები:

1. ინტერფეისისგან არ იქმნება ობიეკტი.

2. Implements საკვანძო სიტყვა გამოიყენება რათა კლასმა მოახდინოს ინტერფეისიდან ინფორმაციის მიღება.

3. როცა ვახდენთ აბსტრაკტული მეთოდების გადაწერას კლასში ყველა მეთოდი უნდა იყოს public მოდიფიკატორით.

4. ინტერფეისი არის სრული აბსტრაქცია.

5. კლასში რომელიც ახდენს ინტერფეისის იმპლემენტირებას აუცილებელია მოხდეს ყველა მეთოდის გადაწერა რომელიც დეკლარირებულია ინტერფეისში. 

6. ინტერფეისის დეკლარირება შესაძლებელია მხოლოდ public და default მოდიფიკატორით. 

7. ყველა მეთოდი ინტერფეისში სტანდარტულად არის აბსტრაკტული და საჯარო( public). ეს ნიშნავს იმას რომ თუ აბსტრაკტულ კლასში აბსტრაკტული მეთოდის დეკლარირებისთვის საჭირო იყო abstract საკვანძო სიტყვა, ინტერფეისში ამის აუცილებლობა არ არსებობს იმიტომ რო ნებისმიერი მეთოდი უკვე აბსტრაკტულია. 

8. ცვლადები რომლის დეკლარირებაც ხდება ინტერფეისში შესაძლებელია იყვნენ მხოლოდ, public, static და final მოდიფიკატორებით. 

9. ცვლადების ინიციალიზება უნდა მოხდეს დაუყოვნებლივ, ინტერფეისში შეუძლებელია იქონიოთ ცვლადი ღირებულების გარეშე. 

10. ნებისმიერი კლასი რომელიც მოახდენს ინტერფეისის იმპლემენტაციას ვეღარ შეუცვლის ცვალდებს ღირებულებას, რადგან როგორც ავღნიშნეთ ცვალდები ინტერფეისში არის public, static და final.

11. კლას შეუძლია მოახდინოს ნებისმიერი რაოდენობის ინტერფეისის იმპლემენტირება. Class Demo implements interface1, interface2, interface3 და ა.შ. მარტივად რომ დაიამხსოვროდ, კლას შეუძლია extends მხოლოდ ერთ კლას ან აბსტრაკტულ კლას მაგრამ შეუძლია იმპლემენტირება უამრავი ინტერფეისის. 

12. ინტერფეის გააჩნია პრივილეგია მრავალ განშტოებიანი მემკვიდრეობის, ამაზე მემკვიდრეობის დროს ვისაუბრეთ, კლას მსგავსი ოპერაციის წარმოების უფელაბა რ აქვს .მემკვიდრეობა, Class exnetds Class1.<-- კლასის მემკვიდრეობა. Interface extends interface1, interface2, interface3 და ა.შ. 

13. ინტერფეის არ შეუძლია ინტერფეისის იმპლემენტირება. 

14. კლას არ შეუძლია მოახდინოს იმპლემენტირება ნებისმიერი ორი ინტერფეისის რომელსაც გააჩნია ერთი და იგივე სათაურის და განსხვავებული Return type-ის მეთოდი.
(უფრო სწორად კომპილატორი მეთოდზე სახელის შეცვლას მოგთხოვთ)

15. ჯავა 8 გვაძლევს უფლებას ინტერფეის დავამატოთ სტატიკური და default მეთოდები. 



ინტერფეისის ქონის არსი მარტივია,ის თავსიებურად წააგავს ხელშეკრულებას პროგრამისტსა და მომხმარებელს შორის, როდესაც შენ კოდს იყენებს მომხმარებელი ის ვალდებული ხდება გამოიყენოს ყველა აბსტრაკტული მეთოდი რომელიც შენ შექმენი, მაგალითისთვის: წარმოიდგინეთ მუშაობთ რომელიმე სოფტ კომპანიაში რომელიც ემსახურება ავტო-ინდუსტრიას, კომპანია წერს კოდს რომელსაც გააჩნია სტანდარტული ქცევის წესები, ავტომატური პარკირება, ავტო-პილოტი, აჩქარება, შენელება, ნებისმიერი ფირმა რომელიც შეიძენს თქვენგან ამ პროგრამას მოახდენს ამ საბაზისო ქცევის წესების იმპლემენტირებას, რა თქმა უნდა ყველა თავისებურად იზამს ამას მაგრამ ყველა ერთი იდეის გარშემო იტრიალებს განსხვავებული სტრუკტურით. უკეთ რომ წარმოვიდგინოთ BMW implements MyCode სადაც მაქ აბსტრაკტული მეთოდები autoParking();autopilot(); speedIncrement(); speedDecrement(); bmw პროგრამისტებს ამ დროს თავიანთი კოდი აქვთ დაწერილი სადაც საბაზისო კლასი ბმვ გახლავთ და რომელსაც გააჩნია ქვე კლასები, bmw500, bmw735, bmw330 implements MyCode, bmw330SpeedTest(){speedIcrement()} ა.შ და ა.შ სტატიკური და default მეთოდის დამატება კი ემსახურება ისევ და ისევ სიმარტივეს. დაუშვათ BMW დაიწყო ავტომობილების წარმოება რომელიც დაფრინავს, fly() მეთოდს ვეღარ დავამატებთ ჩვენ ინტერფეის იმიტომ რო ყველა კომპანია რომელმაც გამოიყენა შენი კოდი მუშაობას შეწყვეტს ერთი მეთოდის გამო და მოუწევთ მთლიანი კოდის გადაწერა, ხვდებით ალბათ რატომაც, ხელშეკრულების დროს მომხმარებელი თანხმდება იმაზე რომ გამოიყენებს ყველა მეთოდს რომელიც დეფინირებულია ინტერფეისში, გამომდინარე აქედან ახალი მეთოდი სათაო ოფისიდან ბევრ პრობლემებს შექმნის. ამიტომაც გვაქ სტატიკური და სტანდარტული მეთოდი რათა ავირიდოთ მსგავსი პრობლემა თავიდან. 

ვნახოთ მაგალითები :


მაგალითი 1: ინტერფეისისგან არ იქმენა ობიეკტი


მაგალითი 2: implements საკვანძო სიტყვა გამოიყენება რათა კლასმა აიღოს ინფორმაცია ინტერფეისისგან


ფოტოზე არა მხოლოდ იმპლემენტირების მაგალის ხედავთ, არამედ მემკვიდრეობისაც, ინტერფეის აქვს პრივილეგია მრავალ განშტოებიანი მემკვიდრეობა აწარმოოს. ის რისი უფლებაც ჩვეულებრივ კლას არ გააჩნია. Demo1 მემკვიდრეობით იღებს ინფორმაციას 2 ინტერფეისისგან რის შემდგომაც ამ იმფორმაციის იმპლემენტირებას ახდენს კლასი. მეთოდები კლასში:

როგორც ხედავთ ყველა მეთოდის გამოყენება გვიწევს რომელიც 3 ინტერფეისშია დეკლარირებული. კომპილირების შემდგომ:

მაგალითი 3: კლასში გადაწერილები მეთოდები აუცილებლად უნდა იყოს public მოდიფიკატორით.


მაგალითი 4: როცა ვახდენთ ინტერფეისის იმპლემენტირებას სავალდებულოა ყველა მეთოდი გამოვიყენოთ, მაგრამ თუ არ გვსურს მეთოდების გამოყენება კლასი შეიძლება მოინიშნოს როგორც აბსტრაკტული. 


როგორც ხედვთ ჯავა არ გვაიძულებს მეთოდების გამოყენებას. 

მაგალითი 5: ყველა მეთოდი არის სტანდარტულად public და abstract მოდიფიკატორით


მაგალითი 6: ცვლადები ინტერფეისში არის static, final და public სტანდარტულად


არ აქვს მნიშვნელობა სტატიკურ, ფინალურ თუ public ცვლადის დეკლარირებას მოახდენთ, ნებისმიერ სიტუაციაში შედეგი ერთია. 

მაგალითი 7: ცვლადების ინიციალიზაცია უნდა მოხდეს ეგრევე:


ანუ არ გაქვთ უფლება მოახდინოთ დეკლარირება და შემდგომ ინიციალიზაცია. თუ არ გახსოვთ რატო ხდება ეგრე ცვალდებს და ტიპებს გადახედეთ. 

მაგალითი 8: კლას არ შეუძლია მოახდინოს იმპლემენტირება ორი ინტერფეისის რომელსაც ერთი და იგივე დასახელების და განსხვავებული return type-ის მეთოდი გააჩნია.



                                                                     მარკერ ინტერფეისი

ინტერფეისი თავისი სტრუკტურიდან გამომდინარე არის ოპერაციების ერთობა რომელიც განსაზღვრავს ობიეკტის ქცევის წესებს, ალბათ გახსოვთ რომ ობიეკტს გააჩნია მდგომარეობა და ქცევის წესები, მეთოდს გააჩნია ატრიბუტები და ქცევის წესები , ინტერფეისი კი არის მხოლოდ ქცევის წესები თქვენსა და მომხმარებელს შორის. ინტერფეისის გამოყენების დროს პროგრამისტს ეძლება პრივილეგია მიაღწიოს პოლიმორფიზმს ძალიან მარტივად. თუ რას ნიშნავს ეს პოლიმორფიზმზე საუბრის დროს მიხვდებით. მარტივი ენით რომ ვთქვათ პოლიმორფიზმი არის ობიეკტზე მრავალი ფორმის მიცემის უნარი. თუ ინტერფეისი ამ ძლიერ ფუნდამეტურ ობიეკტზე ორიენტირებულ პროგრამირებას ემსახურება მაშინ ჩდება კითხვა, რათ გვინდა ცარიელი ინტერფეისი? ცარიელი ინტერფეისი პროგრამირებაში ნაცნობია როგორ მარკერ ინტერფეისი, ან თაგ ინტერფეისი, ან ინტერფეისი მეთოდების გარეშე. მისი გამოყენების იდეა შემდეგში მდგომარეობს, როდესაც კლასი ახდენს ცარიელი ინტერფეისის იმპლემენტირებას ვირტუალურმა მაქნანამ იცის რომ ესა თუ ის ოპერცია ამ კლასიდან უნდა შესრულდეს, მაგალითად მარკერ ინტერფეისი Cloneable, როდესაც კლასი მის გამოყენებას ახდენს ვირტუალური მანქანა მოლოდინშია რომ ამ კლასიდან შექმნილი ობიეკტის კლონირება მოხდება, როცა ვიყენებთ Serializable ინტერფეის მაშინ ვირტუალური მანქანა მოლოდინშია რომ მოხდება ობიეკტიდან ინფორმაციის წაკითხვა და მისი ფაილად ან მონაცემთა ბაზად გადაქცევა ან პირიქით, ფაილიდან და მონაცემთა ბაზიდან ინფორმაცია დაბრუნდება მეხსიერებაში . ცარიელ ინტერფეისების უკან დგას ფუნქციონალიზმი რომელიც ამ მოლოდინს აკონტროლებს რომელსაც ჩვენ ვერ ვხედავთ და რომელზეც ინფორმაციას ვირტუალირი მანქანა ფლობს. სავსებით ლეგალურია შექმნათ საკუთარი მარკერ ინტერფეისი და გამოიყენოთ ის თქვენი სურვილის და მოხედვით. 

ბევრი დამწყები პროგრამისტი იბნევა მარკერ ინტერფეისებზე და არა მხოლოდ ზოგადად ინტერფეისებზე იბნევიან, მაგრამ დამიჯერეთ ფილოსიფია ინტერფეის არ გააჩნია. პრიმიტიული ოპერაცია გახლავთ რომელსაც უზარმაზარი გასაქანი აქვს. ფოტოზე ხედავთ, თუ კლასი არის მემკვიდრე ინტერფეისის მაშინ კლასმა უნდა შეასრულოს ოპერაცია რომელსაც გამოაქვს მასივის შიგთავსი ეკრანზე. 



                                                        ფუნქციონალური ინტერფეისი

Functional Interface გახლავთ ინტერფეისი რომელშიც შესაძლებელია მხოლოდ ერთი ასბტრაკტული მეთოდის ქონა და რომლის ანოტაციაც ხდება @FunctionalInterface. ის შეიმქნა ლამბდა გამოხატულებასთან სამუშაოდ მაგრამ ამაზე ახლა არ ვისაუბრებთ და არც უახლოეს მომავალში. ერთ მაგალითს ვნახავთ და დანარჩენს სხვა დროს გავეცნობით, ახლა რო გავეცნოთ ამ ფუნქციას გაგება გაგიჭირდებათ, ისევე როგორც მარკერ ინტერფეისის გაგება გაგიჭირდათ. მარკერ ინტერფეის ფაილებზე საუბრის დროს გაიგებთ უკეთ და ფუნქციონალურ ინტერფეის ლამბდაზე საუბრის დროს. Junior პროგრამისტებს ამის ცოდნა არ მოეთხოვებათ. მარტივი მაგალითი ფუნქციონალური ინტერფეისის. 


ფუნქციონალურ ინტერფეის შეუძლია ექნეს მხოლოდ ერთი აბსტრაკტული მეთოდი და განუსაზღვრელი ოდენობის სტატიკური და სტანდარტული მეთოდი. 

სხვაობები აბსტრაკტულ კლას და ინტერფეის შორის





                   სხვაობები აბსტრაკტულ კლას და ინტერფეის შორის

            აბსტრაკტული კლასი
                   ინტერფეისი
1.აბსტრაკტულ კლას შეუძლია აწარმოოს მემკვიდრეობა ერთ კლასთან ან აბსტრაკტულ კლასთან
ინტერფეის შეუძლია აწარმოოს მემკვიდრეობა განუსაზღვრელი ოდენობის ინტერფეისებთან
2.აბსტრაკტულ  კლას შეუძლია ექნეს როგორც აბსტრაკტული ისე ყველა სახეობის მეთოდები
ინტერფეის შეუძლია ექნეს მხოლოდ აბსტრაკტული მეთოდები (ჯავა8-ან default და static მეთოდის ქონის უფლება დაემატა)
3.აბსტრაკტული კლასი შეიძლება იყოს მემკვიდრე კლასის ან აბსტრაკტული კლასის
ინტერფეისი შეიძლება იყოს მემკვიდრე მხოლოდ ინტერფეისის
4.აბსტრაკტულ კლასში საკვანძო სიტყვა abstract აუცილებელია რათა მოხდეს მეთოდის დეფინირება
ინტერფეიში by default მეთოდი აბსტრაკტულია.
5.კლას შეუძლია იყოს მემკვიდრე მხოლოდ ერთი აბსტრაკტული კლასის
კლას შეუძლია იმპლემენტირება უამრავი ინტერფეისის
6.აბსტაკტულ კლას შეუძლია ექნეს აბსტრაკტული მეთოდი protected და public მოდიფიკატორით
ინტერფეისში მეთოდი მხოლოდ public მოდიფიკატორით გვხვდება.
7.აბსტრაკტულ კლასში შესაძლებელია ყველანაირი ცვლადის ქონა ყველა სახის მოდიფიკატორით
ინტერფეისში ცვლადები სტანდარტულად public static final (Constant) მოდიფიკატორით გვხვდება.

რჩევა: როგორც წესი ინტერფეისის დასათაურება ხდება ზედსართავებით, runable, walkable, sleepable, cloneable და ა.შ. ზედსართავი იდეალურად ასახავს ინტერფეისის ქცევის წეს. 



                                                                         Polymorphism

პოლიმორფიზმი ჯავაში არის ობიეკტზე მრავალი ფორმის მიცემის უნარი, ყველაზე ხშირად პოლიმორფიზმს ხვდებით მაშინ როცა საბაზისო კლასის ცვლადი მიგვითითებს ხოლმე ქვე კლასის ობიეკტზე. ყველა ჯავა ობიეკტი რომელსაც გააჩნია უნარი გადაცეს ერთზე მეტი IS-A ურთიერთობა არის პოლიმორფიული. მაღლა ვახსენე რო ინტერფეისი ყველაზე მარტივი გზა გახლავთ რათა მივაღწიოთ პოლიმორფიზმს , თუ რატომ ახლა გავერკვევით. წარმოიდგინეთ გაქვთ ინტერფეისი, რომელშიც გვაქვს აბსტრაკტული მეთოდი და რომლის გამოყენებასაც ახდენს უამრავი კლასი, გამომდინარე აქედან უამრავ ობიეკტს აქვს საკუთარი ქცევის წესი რომელიც ნაკარნახებია ერთი კლასიდან, როდესაც შევქმნით ცვლადს ინტერფეისისთვის და მიუთითებთ ობიეკტზე მაშინ ყველა მითითებული ობიეკტი იქნება ამ ინტერფეისის ტიპის შესაბამისად კომპილირების შემდგომ მოხდება ყველა ცალკე მდგომი ობიეკტის კომპილირება სხვა და სხვა შიგთავსით. წაკითხვით შეიძლება რთულად ჯღერს მაგრამ მაგალითებზე ადვილად გაერკვევით. პოლიმორფიზმის მიღწევა შესაძლებელია კლასით და აბსტრაკტული კლასითაც. მთავარი მოთხოვნა რაც პოლიმორფიზმს გააჩნია ეს არის რომ რამოდენიმე კლას უნდა გააჩნდეს ერთი საბაზისო კლასი, კლასები კი საბაზისო კლასის ტიპის უნდა იყვნენ. 

ძირითადი პრივილეგიები პროლიმორფიზმის:

1. ის ფართოდ გამოიყენება მემკვიდრეობის რეალიზაციის დროს. 

2. ის თამაშობს ძირითად როლს ობიეკტების დანიშბულებისამებრ გამოყენებაში, რომლებიც არიან განსხვავებული შიგთავსით მაგრამ საერთო ინტერფეისით, კლასით ან აბსტრაკტული კლასით. 

3. ქცევის წესები დამოკიდებულია ტიპებზე, რომელსაც მუშაობის დროს ვიყენებთ

4. პოლიმორპიულ ოპერაციას აქვს განსხვავებული ქცევის წესები განსხვავებულ სიტუაციებში

5. პოლიმორფიზმი ეს არის ფუნქცია რომელიც გვაძლევს საშუალებას ერთი ინტერფეისით, (კლასით) მოვახდინოთ ზეგალვენა მრავალ კლასზე. 

პოლიმორფიზმი ძალიან გავს მემკვიდრეობას, ხშირად ეს ხდება პრობლემა დამწყებ პროგრამისტებში, რადგან ვერ ხედავენ ძირითად სხვაობას ამ ორ კონცეპციას შორის. მარტივი დეფინირება -> სხვაობის არის შემდეგი:


„მემკვიდრეობა გამოიყენება რათა ქვე კლასმა მიიღოს საბაზისო კლასის ფუნქციონალიზმი და შიგთავსი“



„ფოლიმორზიმი გამოიყენება რათა ქვე კლასმა შეცვალოს საბაზისო კლასის ფუნქციონალიზმი და შიგთავსი“ (ნაწილობრივ ან მთლიანად)


პოლიმორფიზმს გააჩნია სახეობები, ესენია: Parametric, Coercion, Inclusion, Static და Dynamic. ყველა სახეობას არ განვიხილავთ, რადგან ამის აუცილებლობა დამწყებთათვის არ არსებობს, ვისაუბრებთ მხოლოდ დინამიურ და სტატიკურ პოლიმორფიზმე. მასზე ნაწილობრივ ვისაუბრეთ მემკვიდროების დროს მაგრამ ახლა დეტალურად გავეცნობით. 

დინამიური პოლიმორფიზმი. (Run time polymorphism):

მეთოდის გადაწერა ნათელი მაგალითია დინამიური პოლიმორფიზმის. წარმოიდგინეთ გვაქ კლასი „ქცევა“ სადაც დეფინირებული გვაქ მეთოდი მოძრაობა(); ღიმილი(); და ნებისმიერი სხვა ქცევის წესი რომელიც ყოველ-დღიურად თან გვდევს ყველას. როდესაც კლას „ქცევის“ იმპლემენტაციას მოახდენს გიორგი უნივერსიტეტში, ის გადაწერს ყველა მეთოდს რომელიც ზემდგომ კლას გააჩნია, უნივერსიტეტში გიორგი არ იღიმის, სერიოზულია. მოძრაობის კათედრის მიმართულებით , ის სტუდენტია. ა.შ და ა.შ შემდგომ სიტუაციაში გიორგი მგზავრია, ის მოძრაობს საზოგადოებრივი ტრანსპორტით, შემდეგ სიტუაციაში მყივდველია მაღაზიაში, ის მოძრაობს დახლისკენ. საბაზისო კლასი ამ სიატუაციაში ქცევის წესია, რომლისგანაც ინფორმაციას იღებს უნივერსიტეტი, მაღაზია, საზოგადოებრივი ტრანსპორტი, ობიეკტს როცა შექვმნით ამ ოპერაციებისგან -> ქცევის წესი = უნივერსიტეტს. ქცევის წესი =საზოგადოებრივ ტრანსპორტს და ქცევის წესი = მაღაზიას. წესი.იმოძრავე მეთოდით ყველა ობიეკტი განსხვავებულად ამოძრავდება. მათ ერთი რეფერენციული ცვლადი აქვთ მაგრამ განსხვავებული ქცევის წესი რადგან სხვა ობიეკტებმა მისი გადაწერა მოახდინეს, ამიტომაც გადაწერა არის ნათელი მაგალითი დინამიური პოლიმორფიზმის. დინამიური შეკვრა რაც არის მემკვიდრეობიდან გემახსოვრებათ. დინამიური პოლიმორფიზმი იდენტურია დინამიური შეკვრის. ერთი რეფერენციით ხდება უამრავი ობიეკტის ამოძრავება და ვირტუალური მანქანა პროგრამის გაშვების მომენტში ხვდება რომელმა როგორ უნდა იმოძრაოს. (At Run Time) 

მაგალითი დინმიურ პოლიმორფიზმე:


გვაქ 5 კლასი, 1 სააბზისო კლასი, 1 ძირითადი კლასი და 3 ქვე კლასი, საქართველოს ბანკი, თბს ბანკი და უნიკრედით ბანკი მემკვიდრეა აბსტრაკტული კლასის რომელსაც Banking ქვია. ბანკინგის შიგთავსი
ქვე კლასებში მეტნაკლებად იდენტური ინფორმაცია ინახება ამიტომ არ გაჩვენებთ. 

ამის შემდგომ ვქმნით ობიეკტებს ყველა ბანკისთვის:


ასე გამოიყურება დინამიური პოლიმორფიზმი, არც ერთმა ცვლადმა ამ მომენტისთვის არ იცის რომელი ოპერაციის გაშვება უწევს, მაგრამ At Run Time ვირტუალური მანქანა გაერკვევა:


საქართველოს ბანკის ანგარიშზე მაქ დამატებითი მეთოდი, საკრედიტო ბარათზე და უნიკრედიტში მაქ დამატებითი მეთოდი თანხის მოხსნაზე, თუმცა ამ ცვალდებით მათ გამოძახებას ვერ მოვახერხებთ რადგან იგივე მეთოდები არ არის სუპერ კლასში. მოვახდენთ DownCastings რათა ამ მეთოდებს მივწვდეთ:


კომპილირების შემდგომ:




სტატიკური პოლიმორფიზმი: (Compile Time Polymorphism)-ის მაგალითია მეთოდის გადატვირთვა (Overloading), გადატვირთვა იმედია გახსოვთ რაც არის, ის პოლიმორფიული ოპერაცია გახლავთ იმიტომ რო მეთოდებს გააჩნიათ ერთი და იგივე დასახელება მაგრამ განსხვავებული ტიპების და არგუმენტების მატარებლები არიან, ამიტომაც ის ბუნებით პოლიმორფიულია რადგან ერთი სათაურით ასრულებს განსხვავებულ ოპერაციებს. სტატიკური პოლიმორფიზმი იდენტურია სტატიკური შეკვრის, რომელზეც მემკვიდრეობის დროს ვისაუბრეთ. როდესაც მას ვიყენებთ კომპილატორმა წინასწარ იცის ესა თუ ის ოპერაცია რა შედეგით დასრულდება, მას არ უწევს გარკვევა კომპილირების მომენტში არამედ პროცესში. როგორც ესეთი გადატვირთვა ცუდი მაგალითია სტატიკური პოლიმორფიზმის მაგრამ მარტივად გასაგებია ამიტომაც მოვიყვანთ მაგალითად:



ერთი და იგივე სათაურით ობიეკტმა მიიღო განსხვავებული ქცევის წესები.





                                                                             Encapsulation

ენკაპსულაცია ჯავაში არის მექანიზმი რომლის მეშვეობითაც ვახდენთ ცვლადების და მეთოდების ერთ ოგანიზმად ქცევას. პროცესში კი მომხმარებელს ვაძლევთ უფლებას ნახოს ის რისი ნახვის უფელაბასაც ვაძლევთ და დავმალოთ მნიშვნელოვანი შიგთავსი. (დაწერის ან წაკითხვის მიზნით). ეს გვაძლევს საშუალებას კოდის ხელმეორედ გამოყენების, ცვლილებების შეტანის და განახლების ისე რო სხვა კოდი ამით არ დაზიანდეს. ენკაპსულაცია უმთავრესი პრინციპია ობიეკტზე ორიენტირებულ პროგრამირებაში. სხვა კუთხით რომ შევხედოთ ის გარკვეულ წილად ბარიერია შემქნელსა და მომხმარებელს შორის. რომელიც ეფეკტურად ახდენს ფუნქციონალიზმის დამალვას. 

ენკაპსულაციის პრივილეგიები:

1. კლასის ველები შეიძლება შექმნილ იქნეს წაკითხვის ან დაწერის მიზნით.

2. კლას აქვს პრივილეგია იქონიოს სრული კონტროლი იმაზე თუ რა ინახება მის ველში. 

3. მომხმარებელმა არ იცის როგორ ინახება მის მიერ შეყვანილი იმფორმაცია ცვლადში, კლას შეუძლია შეცვალოს ცვლადის ტიპი და ეს მოქმედება არ აისახება მომხმარებელზე, მას არაფრის შეცვლა არ მოუწევს. 

4. ის აუმჯობესებს კოდის შეკეთების, ხელმეორედ გამოყენების და განახლების პროცეს. 

5. ობიეკტი მალავს დატას და მისი იმპლემენტირების დეტალებს გარე სამყაროსგან, თუ წარმოვიდგენთ ობიეკტი ენკაპსულაციის დროს შავი ყუთის როლს ასრულებს, რომელსაც გააჩნია გარკვეული ქცევის წესები. 

6. სწორედ გარკვეული ქცევის წესებია გამოსადეგი მომხმარებლისთვის ან სხვა ობიეკტისთვის. 

7. ნება დართული მეთოდები რომელიც ობიეკტს გააჩნია მოქმედებენ როგორც ინტერფეისი სხვა ობიეკტებისთვის ან მომხმარებლისთვის. 



დეფინირება:


„ეკაპსულაცია არის პრაკტიკა შევკრად მეთოდები და ცვლადები ერთ ოგანიზმად კლასში, რომელსაც გააჩნია 4-ვე საფეხურის მხედველობა, რაც უფლებას გვაძლევს დავიცვათ კოდი არა სასურველი შეღწვისგან “


სრულ, 100% ენკაპსულაციას შესაძლებელია მივაღწიოთ კლასის private წევრებით მხოლოდ, ნაწილობრივი ენკაპსულაციის მიღწევა შესაძლებელია public და protected მოდიფიკატორებით. 

ყველაზე გამოყენებადი პრაკტიკა ენკაპსულაციის დროს არის getter and setter-ის გამოყენება. 

წარმოიდგინეთ გვყავს მომხმარებელი რომელსაც შეუქმენით ინტერფეისი და რომელიც მუშაობს მონაცემთა ბაზასთან, მონაცემთა ბაზაში მას აქვს გარკვეული დაშვების დონე რომელიც მხოლოდ ინფორმაციის წაკითხვის უფლებას აძლევს, (მომხმარებელი იყოს ბანკის თანამშრომელი, ოპერატორი). როგორ შევქმნათ მსგავსი კოდი რომელიც მხოლოდ წაკითხვის უფელაბს მიცემს თანამშრომელს? ვნახოთ მაგალითი რაც ნათელს მოფენს ენკაპსულაციის ფუნდამენტურ პრიცნიპებს:


ეს არის კლასი რომელსაც აქვს დაშვება მონაცემთა ბაზაზე. (მონაცემთა ბაზაზე არაფერი არ არის კლასში იმიტომ რო ჯერ არ გვისაუბრია მასზე, მსგავსი კლასი რომ შევქმნათ დრაივერები უნდა დავაყენოთ, sql ბრძანებები უნდა გამოვიყენოთ და შემდგომ გამოვიყენებდით ამ კლას, რეალურ სიტუაციაში)



ეს არის კლასი რომელიც ოპერატორს მოემსახურება:


შეამჩნევდით რომ მთლიანი ინფორმაციის ენკაპსულაციას ვახდენთ კლიენტის კლასში და დაშვების დონეს ვაკონტროლებს ოპერატორის კლასიდან. რის შემდგომაც ვქმნით ობიეკტს რომელსაც  1 მეთოდი ექნება getClientDB საიდანაც მოახერხებს ინფორმაციის წაკითხვას.
წარმოიდგინეთ ახლა რომ ამ ერთი მეთოდისთვის გვაქ შექმნილი ვიზუალი და ღილაკი. სადაც ოპერატორი შეიყვანს მომხმარებლის სახელს და გვარს, უკან კი დაუბრუნდება მთლიანი ინფრომაცია. 

უამრავი რამის დამატება და გათვალისწინება შეიძლება მოცემულ სიტუაციაში, თუ მსგავსი სახელით არსებობს უკვე მომხმარებელუ დამატებითი მეთოდის ან პარამეტრის შექმნა ტელეფონის ნომრისთვის ან ანგარიშის ნომრისთვის და ა.შ მაგრამ ამაზე საუბარი არ ღირს, მთავარი პრინციპი რაც ამის უკან დგას არის ენკაპსულაცია. მეთოდები და ცვალდები მუშაობენ როგორც ერთი ორგანიზმი სადაც მეთოდების საშუალებით ვახდენთ სრულ კონტროლს ცვალდების, ჩვენ კოდში რომ ინტ ღირებულება ლონგით შევცვალოთ ამას მომხმარებელი ვერც გაიგებს. მეთოდს რო სახელი შეუცვალოთ და ბევრი სხვა რამ რისი მოდიფიცირების სურვილიც გაგვიჩდება სრულიად უვნებლად ჩაივლის მომხმარებლისთვის. ენკაპსუალცია ხშირ შემტხვევაში აბსტრაქციასთან ერთად მუშაობს, აბსტრაქცია არის ინტერფეისი, დაუშვათ მართვის პულტი და ტელევიზორი, ეს არის აბსტრაკტული ურთიერთობა მაგრამ ეკრანს მიღმა რაც ხდება (ფუნქციონალიზმი) არის ენკაპსულაცია, ის დამალულია მომხმარებლისგან. 



ამით მოვრჩით საუბარს Oop-ზე. მისი ცოდნა სასურველი არ არის, მისი ცოდნა აუცილებელია. “Learning Oop in Java is MUST” ბევრი პრიმიტიული მაგალითი ნახეთ 4 კონცეპციაზე საუბრის დროს, ბევრი წესი გაითავისეთ, მისი გამოყენება საკუთარ ლოგიკაზე მორგებით თქვენი მოვალეობა იქნება. მე გამიზნულად არ ვწერდი ლოგიკურ მაგალითებს რათა საკუთარი აზრის თავზე მოხვევა არ გამომსვლოდა და ვცდილობდი მაქსიმალურად მარტივი ენით მესაუბრა. საუბრის დროს დიდი ნაწილი დავფარეთ მაგრამ დარჩა მცირედი რომლის არ ცოდნაც დიდად არ დაგაზიანებთ. შემდეგი ბლოგები იქნება Advanced დონის, სადაც ნაკლებად ვისაუბრებ წესებზე და მეტს გამოყენების რეალურ პრაკტიკაზე. წარმატებები.

კითხვები თუ გაგიჩდათ შეგიძლიათ მომწეროთ მაილზე. 

No comments:

Post a Comment