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 დონის, სადაც ნაკლებად ვისაუბრებ წესებზე და მეტს გამოყენების რეალურ პრაკტიკაზე. წარმატებები.

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

Saturday, 7 January 2017

ობიეკტზე ორიენტირებული პროგრამირება. ნაწილი 1. მემკვიდრეობა



           ობიეკტზე ორიენტირებული პროგრამირება - OOP



სანამ OOP-ზე ფუნდამენტურად დავიწყებდეთ საუბარს ერთ მნიშვნელოვან ფაკტორს მინდა გაუსვა ხაზი, ობიეკტზე ორიენტირებული პროგრამირება ნებისმიერი ჯავა პროგრამისტის მოვალეობა გახლავთ, რადგან მთლიანი პრინციპი ჯავა პროგრამირების ამ იდეაზეა აგებული. ყველაფერი რასაც აკეთებთ კოდის წერის დროს ემსახურება ერთი დიდი პროგრამული ხის შექმნას სადაც ერთი ობიეკტი, მეთოდი თუ ცვლადი ემსახურება მეორეს. Simula პირველი პროგრამული ენაა რომელიც oop პრინციპებით შეიქნა ნორვეგიაში 1960 წელს Ole Johan Dahl და Kristen Nygaard-ის მიერ. შემდგომ შეიქმნა Smalltalk 1970 წელს და დღესდღეობით მათ მიერ შექმნილი პარადიგმებით ხელმძღვანელობენ ისეთი პოპულარული oop ენები, როგორიც გახლავთ java, c++, python, ruby, perl, Delphi და სხვანი. 

ობიეკტზე ორიენტირებული პროგრამირების შექმნის იდეა ემსახურება პროგრამისტისთვის კოდის გაგების სიმარტივეს, თუნდაც ეს კოდი მის მიერ იყოს შექმნილი, მთავარი პრობლემა რომელსაც პროგრამირების დროს აწყდება პროგრამისტი გახლავთ გაურკვევლობა, წარმოიდგინეთ წერთ კოდს, და მას უბრუნდებით თვეების ან წლების შემდგომ, 99%-ის თავისივე კოდი გაუგებარია, არ ახსოვს ეს რატომ დაწერა ან რას ემსახურებოდა მის მიერ შექმნილი კოდი. ამ პრობლემის გადაჭრის მიზნით შეიქმნა oop, რომელიც გვაძლევს საშუალებას კოდი ხელმეორეოდ გამოვიყენოთ და განვაახლოთ. სანამ ოოპ შეიქმნებოდა ყველა წერდა სტრუკტურულად(პროცედურულად) პროგრამირების ენაზე, დღესაც ბევრი ენა სტრუკტურულად ორიენტირებულია რაც ნიშნავს იმას რომ ყველაფერი რაც გაგაჩნია გაქვს ერთ „კლასში“ და მთლიანი კოდის კონტროლს ახდენ code flow-ის მეშვეობით. (if else statmenets, swich statements და ა.შ) ეს ერთის მხრივ მარტივი გზა არის რადგან ქმნი კოდს, რომელიც იდეალურად მუშაობს, რითაც ყველა კმაყოფილია მაგრამ დროთა განმავლობაში შენი ნამუშევარის მოდიფიცირება რო გინდება ვერ ახერხებ, იმიტომ რო ძალიან რთულია დებაგირება, რთულია კოდის ხელმეორედ გამოყენება, რთულია შესწორებების შეტანა, შესაბამისად ყველაფერი ერთმანეთზეა მიბმული, , ყველაფერი ზემოთ თქმული იკავებს უამრავ დროს რაც შეუთავსებელია მოთხოვნასთან და შემოსავალთან. შედეგად დგება დრო რომელსაც სოფტ კრიზისი ქვია, oop-ს შექმნით, შეიქმნა კოდის წერის სტრუკტურა რომელიც იდეალურად იმუშავებდა და ამავდროულად იქნებოდა მარტივად გამოყენებადი, ცვლადი და განახლებადი. 

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

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

1. მემკვიდრეობა. (inheritance) 

2. აბსტრაქცია (abstraction)

3. ენკაპსულაცია (encapsulaiton)

4. პოლიმორფიზმი (polymorphism)



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

მემკვიდრეობა ხდება საკვანძო სიტყვა extends-ის მეშვეობით, როდესაც ერთი კლასი (ქვე კლასი ) extends (საბასიზო კლასს) ის მისგან ღებულობს მთლიან შიგთავს რომელიც საბაზისო კლას გააჩნია, ყველა მეთოდს და ცვლადს რომელიც მასშია დეფინირებული და დამატებით გეძლევათ საშუალება ქვე კლასში მოახდინოთ დამატება ახალი მეთოდების და ცვლადების რომელიც ობიეკტის სრულყოფაში დაგეხმარებათ. მარტივად რომ წარმოიდგინოთ მემკვიდრეობა უყურეთ მას როგორც დაუსრულებელ გეგმას, რომლისგანაც ახდენთ უამრავი გეგმის დასრულებას, მაგალითად: ავტომობილი. მას გააჩნია ძრავი, საბურავები, საჭე, მუხრუჭები, აჩქარება და შენელება, მაგრამ ავტომობილი არის უამრავი სახეობის, Ford, BMW, Kia და ა.შ. ყველა მარკის ავტომობილს აქვს განსხვავებული მონაცემები მაგრამ საბაზისო ერთობა, (ყველა ავტომობილია), გამომდინარე აქედან Ford არის ავტომობილი, BWM არის ავტომობილი, Kia არის ავტომობილი. საერთო საბაზისო მონაცემებით მაგრამ განსხვავებული სტრუკტურით. სხვანაირად ამ სახის მემკვიდრეობას IS-A ურთიერთობას ეძახიან, inheritance = IS-A Relashionship (kia is a vehicle, programmer is a employee, phone is a mobilephone და ა.შ) დეფინირების მაგალითი.



მემკვიდრეობას გააჩნია სახეობები. ესენია:

1. ერთ საფეხურიანი მემკვიდრეობა. როდესაც ერთი კლასი მემკვიდრეა მეორე კლასის. 


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

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


მემკვიდრეობის გამოყენების წესები:


1. არ არის ნება დართული მრავალ განშტოებიანი მემკვიდრეობა. (Class can not extend more the one class)

2. კონსტრუირება ახალი კლასის ხდება უკვე არსებული კლასის ბაზაზე. 

3. მემკვიდრეობით გადაიცემა ყველა მეთოდი დ ცვლადი რომელიც საბაზისო კლას გააჩნია. გარდა კონსტუკტორისა.

4. ძირითად კლას ქვია საბაზისო კლასი, სუპერ კლასი, მშობელი კლასი. 

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

6. საკვანძო სიტყვა super-ის მეშვეობით ხდება საბაზისო კლასის კონსტუკტორზე, ცვლადებზე და მეთოდებზე წვდომა. ის წააგავს this საკვანძო სიტყვას, და ემსახურება საბაზისო კლასის წევრების განსხვავებას ქვე კლასის წევრებისგან. Super(), super.field, super.method(). მას ვერ გამოიყენებთ სტატიკურ წევრებთან. 

7. მონაცემთა ტრანზიტულობა, თუ ძაღლი მემკვიდრეა ცხოველის და პიტბული მემკვიდრეა ძაღლის მაშინ პიტბული მემკვიდრეა ცხოველის. 

8. მემკვიდრეობით გადაიცემა public და protected წევრები.

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

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

11. საბაზისო კლასიდან მემკვიდრეობით მიღებული მეთოდები შეიძლება იქნენ ჩანაცვლებულნი. (overridden). 

12. სტატიკურად მიღებული მეთოდები შეიძლება დაიჩრდილნონ.

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

14. სტანდარტულად ყველა მეთოდი კლასში არის ვირტუალური. 

15. თუ სურვილი გაქვთ რო მეთოდი არ იყოს ვიარტუალური უბრალოდ მონიშნეთ ის როგორც final 

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



                                        HAS-A Relashionship
Has-a ურთიერთობები ერთ-ერთი ფუნდამენტია Oop-ში, მისი საბაზისო სტრუკტურა შემუშავებულია UML-ის (Unified Modeling Language) მიერ. ჯავაში ყველაზე ხშირად გამოიყენება სამი ძირითადი კონცეპცია მოდელირების ზემოთ ხსენებული ენიდან, ესენია: ასოციაცია, აგრეგაცია და კომპოზიცია. 

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

მაშ ასე:

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

კლასი Key:
კლასი Owner:
როგორც შეამჩნევდით ერთი კლასი მეორე კლასში გამოყენებული გვაქ როგორც ტიპი. ამ სახის გამოყენებას bidirectional association ქვია, ცნობისთვის ასოციაციას აქვს ურთიერთობის ფორმები, ესენია, ერთი-ერთან, ერთი-ბევრთან, ბევრი-ერთთან და ბევრი ბევრთან. პრინციპი ყველას ერთია ამიტომ სათითადო არ განვიხილავთ, ერთი თუ იცი ყველა იცი. 

ძირითადი კლასი;

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


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


დეპარტამენტის კლასი.

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

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



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

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

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

საბაზისო კლასი, კონსტრუკტორით და პარამეტრებით. 

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

ძირითადი კლასი და შემდგომ კომპილაცია.

Super საკვანძო სიტყვის მაგალითი:

საბაზისო კლასი.

ქვე კლასი:

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


Override:

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

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

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

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

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

1. მაგალითი:

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

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

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

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

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

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

                                                                Static & Dynamic Binding

Static Binding- არის პროცესი რომელიც ხდება კომპილირების დროს(at compile time), მას სხვანაირად ნაადრევ კავშირს ეძახიან, ყველა, სტატიკური, ფინალური და პრივატული მეთოდი კავშირში შედის ვირტუალ მანქანასთან კომპილირების დროს, ანუ ვირტუალურმა მანქანამ წინასწარ იცის ესა თუ ის ოპერაცია რა შედეგით დასრულდება, ადვილად წარმოდგენისთვის სტატიკურ კავშირს დავარქვათ ინფორმაციის ნაადრევი მიღება, ეგ არის მისი მოვალეობა და არაფერი სხვა, მაგალითიც არა ერთი გაქვთ ამ ოპერაციის ნანახი, 
ფოტოზე ხედავთ სტატიკური ურთიერთობის მაგალითს, ასეთ სიტუაციაში ვირტუალურ მანქანას არ უწევს ორ აზროვნებაში გარკვევა. ზუსტად იცის რომელ მეთოდს იძახებს. 
დინამიური კავშირი : არის დაგვიანებული ურთიერთობა, ასეთ სიატუაციაში ვირტუალურმა მანქანამ ბოლო მომენტამდე არ იცის რომელი ბრძანება გაუშვას, ის ერკვევა ბრძანებაში გაშვების პროცესში (at run time). მეთოდის გადაწერა ნათელი მაგალითია დინამიური კავშირის, ვირტუალური მანქანა მეთოდის გადაწერის დროს ბოლო მომენტში ერკვევა რომელი ბრძანების გაშვება უწევს, იმიტომ რო ერთი და იგივე დასახელების, პარამეტრების ოდენობის მეთოდებთან უწევს მუშაობა. 
ფოტოზე ხედავთ სტანდარტულ მაგალითს დინამიური კავშირის. კომპილირების შემდგომ:
დინამიურ და სტატიკურ კავშირზე საუბრის დროს ერთ-ერთი აზრი რაც მოგდის ხოლმე თავში ეს გახლავთ კასტინგი. კასტინგი არა ტიპებს არამედ ობიეკტებს შორის, ერთი ობიეკტის მეორე ობიეკტად გადაქცევა და პირიქით. გახსოვთ ალბათ რო ჯავაში ყველაფერ იწყება ძირითადი კლასიდან რომელსაც ობიეკტი ქვია. ობიეკტის მემკვიდრეა ყველა და ყველაფერი რაც იქნება ჯავა ბიბლიოთეკის გამოყენებით. შესაბამისად ობიეკტი არის სუპერკლასი ყველა კლასის და ზემდგომი ობიეკტი ყველა ობიეკტის.

UpCasting:

კომპილირება: 

განვიხილოთ რა მოხდა ფოტოზე. გვაქ კლასი სადაც გვაქ მცირე ინფორმაცია, შემდგომ კლასიდან ვქმნით ობიეკტს. და ამ ობიეკტის ცვლადს ვანიჭებთ ზემდგომ ობიეკტს.(ცნობისთვის, ობიეკტზე მაგალითი ყოველთვის დადებით შედეგამდე მიგიყვანთ და არ არის კარგი პრაკტიკა ეგეთი სახით მაგალითის ჩვენება, მაგრამ ნებისმიერ სხვა კლასზე რო გაიმეოროთ იგივე ოპერაცია იგივე შედეგს მიიღებთ, ამიტომ მეპატიება სიზარმაცე. ) გამომდინარე აქედან ზემდგომი ობიეკტი გადაიქცა(ვირტუალურად, კომპილატორისთვის) ქვე მდგომ ობიეკტად. Object obj = upcast; ამ ოპერაციის დროს. ჯავა მსგავსი ოპერაციის წარმოებას საკუთარ თავზე იღებს, რატომ? იმიტო რო მსგავსი ოპერაციის წარმოების დროს მინიმალური შანსია იმისთვის რო რამე გაუთვალისწინებელი მოხდეს, ანუ საფრთხე ფაკტიურად არ არსებობს. ამიტომაც ზედმეტი ფიქრი არ გვჭირდება. მოცემულ ოპერაციას ვამოწმებთ instanceof საკვანძო სიტყვის მეშვეობით, რომელიც ამოწმებს მემკვიდრეობას. და პასუხიც დადებითი გვაქ. შემდეგ ველზე ეგ კონვერტირება მაქ განვრცობილი, ვერ ვხედავთ მაგრამ ოპერაცია Object obj1 = (Object)new UpCastingAdnDownCasting(); ამ პრინციპით ხდება კადრს მიღმა.  ეს არის სრული ვერსია იმისა რასაც ჯავა ჩვენთვის აკეთებს. შემდგომ ამასაც ვამოწმებთ და პასუხი ისევ დადებითია. მესამე ვარიანტი გამომრჩა. Object obj1 = new UpCastingAdnDownCasting(); ასე რო მოვქცეულიყავით, ოპერაცია მაინც ლეგალური იქნებოდა. ნუ რა თქმა უნდა როგორც ყველა წესიერ , პატიოსან და კეთილსინდისიერ ზემდგომ ობიეკტს ისე სუპერ ობიეკტსაც არ აქვს წვდომა ქვემდგომი ობიეკტების მეთოდებზე. თუ მსგავსი დასახელების, პარამეტრების და ოპერაციის მეთოდის მატარებელი არ არის თვითონ. შესაბამისად ჩვენი სუპერ ობიეკტი ვერაფერს ვერ ხედავს იმ ობიეკტში რომელსაც რეალურად ემსახურება და აქ იწყება DownCasting. მაგალითებს ამ კონკრეტულ კლასში განახებთ და მერე ცალკე განვავრცობ. 
ფოტოზე წაიკითხეთ კომენტარი. კომპილირების შემდგომ:


როგორც ხედავთ იდეალურად ართმევს თავს. მაგრამ downCasting არც ისე მარტივია როგორც ეს ერთი შეხედვით ჩანს, მისი წარმოების დროს უამრავი ფაკტორის გათვალისწინება გვიწევს, 1. ის უნდა გამოიყენოთ მაშინ როცა დარწმუნებული ხართ რო დინამიური ოპერაციის დროს შეასრულებს მასზე დაკისრებულ ამოცანას, (At Run Time), და არ გაჩერდება პროგრამა. მაგალითებზე ადვილია შესწორებების შეტანა მაგრამ როცა კოდი დიდია უამრავ დროს წაიღებს ჩასწორება, 2. სწორად უნდა მოახდინოთ კონვერტირება, სწორად კონვერტირებაში მოიაზრება სწორად ობიეკტის შექმნა, უბრალოდ ვერ შექმნით ობიეკტს და მერე ამ ობიეკტს მეორე ობიეკტს ვერ მიაკრავთ. თან ცუდი რაც არის როცა ამას გააკეთებთ ჯავა არანაირ გაამფთხილებელ ნიშანს არ გაჩვენებთ რო ოპერაციის წარმოება საფრთხეს შეიცავს, 3. გაითვალისწინეთ ხშირ შემთხვევაში ვერ მოახერხებთ კასტინგის ზემოდან ქვემოთ წარმოებას, ჯავა ამის უფელაბს უბრალოდ არ მოგცემთ შეუთავსებელი ტიპების გამო. არ არის ფაკტი რო ობიეკტი რომელსაც შექმნით ზუსტად იმ ტიპის იქნება რომელის ღირებულებასაც მას მიანიჭებთ. ამაზე ჯერ კიდევ დსაწყისში ვისაუბრეთ კასტინგის დროს. მსგავს პრობლემები რო აირიდოთ თავიდან ჯობია საერთოდ არ გააკეთოთ. უამრავი საფრთხის შემცველია. ლოგიკურად ჩდება კითხვა თუ ამდენი საფრთხის მატარებელია ზემოდან ქვემოთ წვდომა მაშინ რაღატო ვიყენებთ საერთოდ? 1. იმიტომ რო მივაღწიოთ პოლიმორფიზმს 2. იმიტომ რო პროგრამა გავხადოთ კომპლექსური და რთული (მარტივ ენაზე ინფორმაცია შევფუთოთ ისე რო ჩვენც ვერ გავიგოთ, არა თუ ვინმემ გარედან. ). ß ეს ხუმრობით. 
გამოყენების წესი, downCasting-ს უსაფრთხოდ რო მიაღწიოთ, გადახედეთ თქვენ მიერ შექმნილი კლასების იერარქიას, დაუშვათ აშენებთ შენობებს, გაქვთ ძირითადი კლასი ნაგებობა, სადაც სტანდარტული მონაცემები გაქვთ ნაგებობისთვის შენახული, და ამ ნაგებობიდან იწყებთ მშენებლობას, მის მაგალითზე ააგეთ ბანკის სათაო ოფისი, ბანკმა სათაო ოფისის აგების მერე ააშენა პატარა ოფისები რაიონებში, გამომდინარე აქედან რაიონული ოფისები მემკვიდრეა ნაგებობის იმიტომ რო მის მიერ შექმნილი, მოდელით ხელმძღვანელობს. ძირითადი იდეა რომელიც კასტინგს ეხება ამ მემკვიდრეობის მიღმა გახლავთ: რაიონული ოფისი ბანკის, ბანკია? დიახ. მაშინ შესაძლებელია კასტინგი. სათაო ოფისი ბანკის ნაგებობაა? დიახ, მაშინ შესაძლებელია კასინგი, ნაგებობა რაიონული ბანკია? არა! ნაგებობა სავაჭრო ცენტრიც არის. მაშინ ნუღარ მოახდენ კასტინგს. კოდურ ენაზე ეგ შემდეგნაირად გამოიყურება. Building plan = new Building(); ნაგებობის ობიეკტი. ამის შემდგომ რო ავდგეთ და Bank main = (Bank) plan; მოვახდინოთ downCasting ჯავა ამის უფლებას მოგვცემს, ჯავას ერთადერთი რაც ადარდებს ეგ ფრჩხილებში ობიეკტის ნახვაა, მაგრამ პროგრამას რო გაუშვებ ClaccCastException Error მივიღებთ შედეგად და ბონუსად უამრავ დროსაც დაკარგავთ თუ პროგრამა დიდია. იგივე მაგალითზე Building plan = new Bank() და შემდგომ Bank main = (Bank) plan; სრულიად ლეგალური და უსაფრთხო ოპერაცია გახლავთ, რადგან სწორად მოვახდინეთ downCasting. ყველაფერ ამასთან ერთად გასათვალისწინებელია ტიპებიც, თუ ნაგებობას რამოდენიმე გეგმა აქვს, ბანკისთვის, იურიდიული ფირმისთვის. მაშინ არ არის ფაკტი რომ კონვერტირება მოხდება ნაგებობის. რადგან ზუსტად უნდა ვიცოდეთ რომელი ტიპის მატარებელია. ბანკის(Integer) თუ იურიდიული ფირმის(String), 

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


ფოტოზე ბოლო ორი მეთოდი მაგალითისთვის მაქ ნაჩვენები, downCasting-ის მიზანია რო ყველა ობიეკტი სტანდარტულ საწყისებს დაუბრუნდნენ, 

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

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

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


და ეკრანზე გამოვა 10. 

შემდეგ თავში აბსტრაქციაზე ვისაუბრებთ. 

Objects are like people. They’re living, breathing things that have knowledge inside them about how to do things and have memory inside them so they can remember things. And rather than interacting with them at a very low level, you interact with them at a very high level of abstraction, like we’re doing right here.Here’s an example: If I’m your laundry object, you can give me your dirty clothes and send me a message that says, “Can you get my clothes laundered, please.” I happen to know where the best laundry place in San Francisco is. And I speak English, and I have dollars in my pockets. So I go out and hail a taxicab and tell the driver to take me to this place in San Francisco. I go get your clothes laundered, I jump back in the cab, I get back here. I give you your clean clothes and say, “Here are your clean clothes.”You have no idea how I did that. You have no knowledge of the laundry place. Maybe you speak French, and you can’t even hail a taxi. You can’t pay for one, you don’t have dollars in your pocket. Yet, I knew how to do all of that. And you didn’t have to know any of it. All that complexity was hidden inside of me, and we were able to interact at a very high level of abstraction. That’s what objects are. They encapsulate complexity, and the interfaces to that complexity are high level
                                                                                                                      Steve Jobs

წარმატებები: