ყოველი კლასის ახალი ობიექტი იქმნება კლასის კონსტრუქტორის გამოძახებით. გარდა ამისა ასევე შეუძლებელია ახალი ობიექტის შექმნა არა მხოლოდ ობიექტის ფაქტიური კლასის კონსტრუქტორის გამოძახების გარეშე, არამედ ეს შეუძლებელია ყოველი მისი სუპერკლასის კონსტრუქტორის გამოძახების გარეშე. კონსტრუქტორი არის კოდის ის ნაწილი რომელიც სრულდება ყოველთვის როდესაც ხდება new ოპერატორის გამოყენება.
კონსტრუქტორის საფუძვლები
ყოველ კლასს, აბსტრაქტული კლასების ჩათვლით აუცილებლად უნდა გააჩნდეს კონსტრუქტორი. თუმცა ეს წესი არ გულისხმობს იმას რომ პროგრამისტმა აუცილებლად უნდა განსაზღვროს ის. კონსტრუქტორს აქვს შემდეგი სახე:
1 2 3 4 5 | class Foo { Foo() {} // Foo კლასის კონსტრუქტორი } |
როგორც მაგალითიდან ჩანს, სხვა ჩვეულებრივი კლასის მეთოდებისაგან განსხვავებით კონსტრუქტორს არ გააჩნია დასაბრუნებელი მნიშვნელობის ტიპი. ორი მნიშვნელოვანი დეტალი რაც ახასიათებს კონსტრუქტორს, ეს არის ის რომ მას არ გააჩნია დასაბრუნებელი მნიშვნელობის ტიპი და ასევე მას უნდა ერქვას ზუსტად იგივე სახელი რაც ქვია კლასს. ზოგადად კონსტრუქტორები გამოიყენება კლასის ობიექტის ცვლადების ინიციალიზაციისათვის, როგორც ეს ნაჩვენებია შემდეგ მაგალითში:
1 2 3 4 5 6 7 8 9 10 11 12 |
ზემოთ ნაჩვენებ მაგალითში, Foo კლასს არ გააჩნია უპარამეტრო კონსტრუქტორი. რაც ნიშნავს იმას რომ შემდეგი კოდი არ დაკომპილირდება:
Foo f = new Foo();//არ დაკომპილირდება რადგან არ არსებობს შესაბამისი (უპარამეტრო) კონსტრუქტორი
ხოლო შემდეგი კოდი დაკომპილირდება წარმატებით:
Foo f = new Foo(“Bar”, 43); //დაკომპილირდება, რადაგან გადაცემული პარამეტრები შეესაბამება Foo კონსტრუქტორს
ამ მაგალითიდან გამომდინარე, მიღებულია (და სასურველი) რომ კლასს გააჩნდეს უპარამეტრო კონსტრუქტორი, მიუხედავად იმისა თუ რამდენი გადატვირთული კონსტრუქტორი გააჩნია ამ კლასს (კონსტრუქტორების გადატვირთვა შესაძლებელია). თუმცა ასევე არსებობს შემთხვევები როდესაც უმჯობესია თუ კლასში არ იქნება უპარამეტრო კონსტრუქტორი.
კონსტრუქტორების გამოძახების მიმდევრობა
ცნობილია რომ კონსტრუქტორები გამოიძახება კოდის შესრულების დროს new ოპერატორის გამოყენების შემდეგ, მაგალითად:
1 | Horse h = new Horse(); |
განვიხილოთ თუ რა ხდება როდესაც ვქმნით კლასის ობიექტს (new Horse())
დავუშვათ რომ Horse კლასის მშობელი არის Animal კლასი, ხოლო Animal კლასის მშობელი კლასი არის Object. ასეთ შემთხვევაში კლასის ობიექტის შექმნისას შესრულდება შემდეგი ბიჯები:
- თუკი სხვაგვარად არ არის მითითებული, Horse -ს კონსტრუქტორი ავტომატურად იძახებს მისი მშობელი კლასის უპარამეტრო კონსტრუქტორს (თუკი მშობელს კონსტრუქტორი განსაზღვრული არ აქვს, იძახება ნაგულისხმევი კონსტრუქტორი) ”სხვაგვარად მითითებული” გულისხმობს იმას, რომ Horse კონსტრუქტორს შეუძლია მშობლის კონსტრუქტორის ცხადად გამოძახებაც
- გამოიძახება Animal კონსტრუქტორი (Animal არის Horse კლასის მშობელი (super) კლასი).
- გამოიძახება Object კონსტრუქტორი (რადგან Object კლასი არის საწყისი სუპერკლასი ყველა სხვა კლასისთვის, გამომდინარე აქედან იგი არის Animal კლასის მშობელი კლასი (მიუხედავად იმისა ცხადად დავწერთ თუ არა “extends Object” Animal კლასის აღწერისას)).
- Object კლასის ობიექტის ცვლადებს ენიჭებათ განსაზღვრული მნიშვნელობები (ამ შემთხვევაში განსაზღვრულ მნიშვნელობაში იგულისხმება მნიშვნელობა რომლებიც ენიჭებათ ცვლადებს მათი აღწერის მომენტში მაგ. „int j = 20”, სადაც „20“ არის განსაზღვრული (განსხვავებით საწყისი (ნაგულისხმევი) მნიშვნელობისგან) მნიშნველობა კლასის ობიექტის ცვლადისა).
- Object კონსტრუქტორი ამთავრებს შესრულებას.
- Animal კლასის ობიექტის ცვლადებს ენიჭებათ განსაზღვული მნიშვნელობები (თუ მსგავსი არსებობს).
- Animal კონსტრუქტორი ამთავრებს შესრულებას.
- Horse კლასის ობიექტის ცვლადებს ენიჭებათ განსაზღვული მნიშვნელობები (თუ მსგავსი არსებობს).
- Horse კონსტრუქტორი ამთავრებს შესრულებას.
ცხრილში ნაჩვენებია თუ რა მიმდევრობით გამოიძახება კონსტრუქტორები:
| 4. Object() |
| 3. Animal() იძახებს super() – ს |
| 2. Horse() იძახებს super() – ს |
| 1. main() იძახებს new Horse() – ს |
კონსტრუქტორების წესები
ქვემოთ მოყვანილ სიაში მოყვანილია წესები რომლებიც გააჩნია კონსტრუქტორებს:
- კონსტრუქტორებთან დასაშვებია ნებისმიერი მოდიფიკატორის გამოყენება (private კონსტრუქტორი ნიშნავს იმას რომ მხოლოდ მოცემული კლასის ფარგლებში არსებული კოდის გამოყენებით შეიძლება ამ კლასის ობიექტის შექმნა, თუ საჭიროა ამ კლასის ობიექტის გამოყენება მის გარეთ ასეთ შემთხვევაში კლასს უნდა გააჩნდეს სტატიკური (static) მეთოდი ან ცვლადი რომელიც ამ კლასის ობიექტთან წვდომის საშუალებას მისცემს მის გარეთ მყოფ სხვა კოდს). ასევე არსებობს კიდევ private კონსტრუქტორის კიდევ ერთი გამოყენება, ასეთი კონსტრუქტორის გამოძახება შესაძლებელია იმავე კლასში არსებული სხვა კონსტრუქტორებიდან.
- კონსტრუქტორის სახელი უნდა იყოს იგივე რა სახელიც ქვია კლასს.
- კონსტრუქტორს არ უნდა გააჩნდეს დასაბრუნებელი მნიშვნელობის ტიპი.
- დასაშვებია (მაგრამ აზრს მოკლებული) მეთოდის არსებობა იგივე სახელით რა სახელიც ქვია კლასს. თუ ასეთ მეთოდს გააჩნია დასაბრუნებელი მნიშვნელობის ტიპი ეს ნიშნავს რომ იგი არის მეთოდი და არა კონსტრუქტორი.
- თუ კლასის შიგნით არ არის აღწერილი არცერთი კონსტრუქტორი, ასეთ შემთხვევაში კომპილატორი ავტომატურად დააგენერირებს უპარამეტრო კონსტრუქტორს (ნაგულისხმევი კონსტრუქტორი).
- ავტომატური კონსტრუქტორის გენერაცია ხდება მაშინ და მხოლოდ მაშინ, თუ კლასში სხვა კონსტრუქტორი ცხადად არ არის აღწერილი
- ყველა კონსტრუქტორში პრიველი გამოსახულება ყოველთვის არის ან გადატვირთული კონსტრუქტორის გამოძახება (this()) ან მშობელი კლასის კონსტრუქტორის გამოძახება (super()), ასევე აღსანიშნავია რომ ასეთი გამოძახება შესაძლებელია დააგენერიროს კომპილატორმა.
- იმ შემთხვევაში თუ კონსტრუქტორში არ დავწერთ მშობელი კლასის (super()) ან გადატვირთული (this()) კონსტრუქტორის გამოძახებას, მაშინ კომპილატორი ავტომატურად დააგენერირებს უპარამეტრო super() კონსტრუქტორის გამოძახების კოდს და ჩასვავს მათ კონსტრუქტორის პირველ გამოსახულებად.
- super() მეთოდის გამოძახება შესაძლებელია იყოს როგორც უპარამეტრო ასევე პარამეტრიზებული.
- უპარამეტრო კონსტრუქტორი არ არის აუცილებლად ნაგულისხმევი (default) (ე.ი. კომპილატორის მიერ დაგენერირებული) კონსტრუქტორი, მიუხედავად იმისა რომ ნაგულისხმევი კონსტრუქტორი ყოველთვის არის უპარამეტრო. ნაგულისხმევი კონსტრუქტორი ეწოდება ისეთ კონსტრუქტორს რომელსაც ქმნის კომპილატორი.
- კონსტრუქტორიდან შეუძლებელია კლასის ობიექტის მეთოდის გამოძახება, ან მიმართვა კლასის ობიექტის ცვლადებზე, იქამდე სანამ არ დამთავრდება ყველა მშობელი კლასის კონსტრუქტორების შესრულება. (ეს არ ვრცელდება სტატიკურ მეთოდებსა და ცვლადებზე)
- აბსტრაქტულ კლასებს აქვთ კონსტრუქტორები, ეს კონსტრუქტორები ყოველთვის გამოიძახება როდესაც ხდება კონკრეტული კლასის ობიექტის შექმნა.
- ინტერფეისებს არ გააჩნიათ კონსტრუქტორები. ინტერფეისები არ არინ ობიექტების მემკვიდრული იერარქიის ნაწილი.
- ერთადერთი საშუალება კონსტრუქტორის გამოძახებისა არის მისი გამოძახება სხვა კონსტრუქტორიდან, შეუძლებელია ისეთი კოდის დაწერა რომელიც განახორციელებს უშუალოდ კონსტრუქტორის გამოძახებას:
- class Horse() {Horse() { } //კონსტრუქტორი
1 2 3 | void doCall() { Horse(); //მსგავსი მიმართვა დაუშვებალია! } |
რა შემთხვევაში გენერირდება ნაგულისხმევი კონსტრუქტორი?
როგორც ზემოთ იყო აღნიშნული, კომპილატორი ყოველთვის არ აგენერირებს კონსტრუქტორის კოდს. თუ რა შემთხვევაში ხდება კომპილატორის მიერ კონსტრუქტორის კოდის გენერაცია და რატომ ხდება ასე, განხილულია ქვემოთ მოყვანილ მაგალითებში.
მოცემულ მაგალითში ნაჩვენებია Horse კლასი ორი კონსტრუქტორით:
1 2 3 4 5 6 7 |
ასეთ შემთხვევაში კომპილატორი არ დააგენერირებს კონსტრუქტორს.
განვიხილოთ აღწერილი კლასის სხვა ვარიანტი:
1 2 3 4 5 |
კომპილატორი არც ამ შემთხვევაში დააგენერირებს კონსტრუქტორს.
განვიხილოთ იგივე კლასის შემდეგი ვარიანტი:
1 2 3 | class Horse { } |
ასეთ შემთხვევაში კომპილატორი დააგენერირებს ნაგულისხმევ კონსტრუქტორს მაგალითში მოყვანილი კლასისათვის, იმიტომ რომ კლასში არ არის გამოყენებული არც ერთი კონსტრუქტორი.
რა საშუალებით შეგვიძლია დავადგინოთ თუ რანაირია კომპილატორის მიერ დაგენერირებული კონსტრუქტორი?
- ნაგულისხმევ კონსტრუქტორს აქვს იგივე წვდომის მოდიფიკატორი რაც კლასს.
- ნაგულისხმევ კონსტრუქტორს არ აქვს პარამეტრები.
- ნაგულისხმევი კონსტრუქტორი შეიცავს სუპერ (super) კონსტრუქტორის უპარამეტრო გამოძახებას (super()).
ცხრილში მოყვანილია მაგალითები სხვადასხვა შემთხვევებისათვის, თუ რას აგენერირებს (ან არ აგენერირებს) კომპილატორი:
| ხელით დაწერილი კლასის კოდი | კომპილატორის მიერ გენერირებული კონსტრუქტორის კოდი |
|---|---|
| class Foo {} | class Foo { Foo (){ super(); } } |
| class Foo() { Foo(){ } } |
class Foo { Foo (){ super(); } } |
| public class Foo { } | public class Foo { public Foo (){ super(); } } |
| class Foo { Foo (String s){} } |
class Foo { Foo (String s){ super(); } } |
| class Foo { Foo(String s){ super() } } |
კომპილატორი არ დააგენერირებს კოდს. |
| class Foo() { void Foo(){ } } |
class Foo { void Foo(){ }Foo() { super(); } } |
რა ხდება იმ შემთხვევაში თუ სუპერ კონსტრუქტორს აქვს პარამეტრები?
კონსტრუქტორებს ისევე როგორც მეთოდებს შესაძლოა გააჩნდეთ პარამეტრები. იმ შემთხვევაში თუ მოხდება ისეთი მეთოდის გამოძახება რომელსაც აქვს მაგალითად int ტიპის პარამეტრი, მაგრამ გამოძახებისას მას არ გადაეცამა პარამეტრი ეს გამოიწვევს შეცდომას, როგორც ნაჩვენებია მაგალითში:
1 2 3 4 5 6 7 8 9 10 11 | class Bar { void testInt(int x) { } } class TestBar { public static void main (String[] args) { Bar bar = new Bar(); bar.testInt(); //მეთოდის უპარამეტროდ გამოძახება } } |
ასეთი კოდის შესრულება ცხადია გამოიწვევს შეცდომას, რადგან არ არსებობს შესაბამისი მეთოდი testInt(). შესაბამისობაში აქ იგულისხმება ის რომ მეთოდისთვის გადაცემული მნიშვნელობისა ან ცვლადის ტიპი უნდა შეესაბამებოდეს მისი პარამეტრის ტიპს. აღნიშნული სრულად ეხება კონსტრუქტორებს, მოცემული შემთხვევის მსგავსად კონსტრუქტორების მოქმედებაც არის იდენტური.
თუ სუპერ კონსტრუქტორს (მშობელი კლასის კონსტრუქტორი) აქვს განსაზღვრული პარამეტრები, მაშინ ამ კონსტრუქტორის გამოძახება უნდა მოხდეს შესაბამისი პარამეტრების გადაცემით. გასათვალიწინებელია ის მომენტი, რომ თუ სუპერკლასს არ გააჩნია უპარამეტრო კონსტრუქტორი, აუცილებელია შვილი კლასის კონსტრუქტორში მოხდეს მშობელი კლასის კონსტრუქტორის გამოძახების ჩაწერა შესაბამისი პარამეტრებით. შემდეგ მაგალითში აღწერილია აღნიშნული პრობლემა:
1 2 3 4 5 6 7 8 9 | class Animal { Animal (String name) { } } class Dog extends Animal { Dog() { super(); //შეცდომაა } } |
მოყვანილ მაგალითში შეცდომა მდგომარეობს იმაში, რომ მშობელ Animal კლასს არ გააჩნია უპარამეტრო კონსტრუქტორი რომლის გამოძახებაც მოხდა Dog კონსტრუქტორიდან – super(). ასეთივე შეცდომა წარმოიქმნება შემდეგი შემთხვევისთვისაც:
1 2 3 4 5 |
ამ კოდის კომპილაცია შეუძლებელია, რადგნა როგორც ზემოთ იყო აღწერილი ისეთ შემთხვევაში თუ კლასში არ არის განსაზღვრული არც ერთი კონსტრუქტორი, კომპილატორი დააგენერირებს მას ავტომატურად. ასეთი დაგენერირებული (უპარამეტრო) კონსტური გამოიძახებს მისი მშობელი კლასის უპარამეტრო კონსტრუქტორს (super()), ხოლო რადგან მშობელ Animal კლასში არ არის განსაზღვურლი უპარამეტრო კონსტრუქტორი ეს ავტომატურად გამოიწვევს შეცდომას.
კომპილატორის მიერ მოდიფიცირებულ კოდს აქვს შემდეგი სახე:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class Animal { Animal (String name) { } } class Dog extends Animal { /*კომპილატორის მიერ დაგენერირებული კონსტრუქტორი და სუპერ კონსტრუქტორის გამოძახება.*/ class Dog() { /*გამოძახება გამოიწვევს შეცდომას, რადგან მშობელ კლასში არ არის განსაზღვრული უპარამეტრო კონსტრუქტორი. */ super(); } } |
თუმცა მოყვანილი მაგალითებიდან ცხადია, მაგრამ ხაზგასმით უნდა აღინიშნოს რომ კონსტრუქტორები არ გადაეცემა ქვეკლასებს მემკვიდრეობით რადგან კონსტრუქტორი არ არის მეთოდი. კონსტრუქტორის გადაფარვა შეუძლებელია ქვეკლასში (რადგან კონსტრუქტორი არ არის მეთოდი და მხოლოდ ეგზემპლარის მეთოდების გადაფარვაა დაშვებული). თუმცა კონსტრუქტორების გადაფარვა დაუშვებელია, როგორც ზემოთ მოყვანილი მაგალითებიდან ჩანს მათი გადატვირთვა დასაშვებია.
კონსტრუქტორების გადატვირთვა
კონსტრუქტორის გადატვირთვა ნიშნავს მის რამდენჯერმე დაწერას, ყოველ მათგანს უნდა გააჩნდეს მისთვის შესაბამის და ერთმანეთისგან განსხვავებული პარამეტრები.
1 2 3 4 5 6 7 |
არწერილ Foo კლასს აქვს ორი გადატვირთული კონსტრუქტორი, ერთ ერთი მათგან ღებულობს პარამეტრად სტრიქონს. რადგან უპარამეტრო კონსტრუქტორის შიგნით არ წერია კოდი იგი იდენტურია კომპილატორის მიერ დაგენერირებული კონსტრუქტორისა, თუმცა აღსანიშნავია რომ რადგან აღწერილ კლასში არის ერთი პარამეტრიანი კონსტრუქტორი, კომპილატორი არ დააგენერირებს ნაგულისხმევ კონსტრუქტორს. თუ არსებობს უპარამეტრო კონსტრუქტორის გადატვირთვის საჭიროება პარამეტრიანი კონსტრუქტორის მიერ, ასეთ შემთხვევაში საჭირო უპარამეტრო კონსტრუქტორის დაწერაც. ისევე როგორც ნაჩვენებია მაგალითში.
კონსტრუქტორის გადატვირთვა გამოიყენება ისეთ შემთხვევებში როდესაც საჭიროა კლიენტის აღჭურვა კლასის კონსტრუირების დამატებითი შესაძლებლობებით. მაგალითისათვის, თუ კლიენტმა იცის ცხოველის დასახელება მას შეუძლია იგი გადასცეს Animal კლასის იმ კონსტრუქტორს რომელიც პარამეტრად ღებულობს სტრიქონს. მაგრამ იმ შემთხვევაში თუ კლიენტმა არ იცის ეს სახელი, მას შეუძლია გამოიძახოს უპარამეტრო კონსტრუქტორი და ამ კონსტრუქტორს შეუძლია აირჩიოს საწყისი სახელი. მსგავსი შემთხვევა შეგვიძლია აღვწეროთ ისე როგორც ეს ნაჩვენებია შემდეგ კლასში:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public class Animal { String name; Animal(String name) { this.name = name; } Animal() { this(makeRandomName()); } static String makeRandomName() { int x = (int) (Math.random() * 5); String name = new String[]{"NameOne", "NameTwo", "NameThree", "NameFour", "NameFive"}[x]; return name; } public static void main (String[] args) { Animal a = new Animal(); System.out.println(a.name); Animal b = new Animal("Spot"); System.out.pringln(b.name); } } |
ცხრილში ნაჩვენებია გამოძახებების მიმდევრობა მოყვანილი მაგალითისთვის:
4. Object()
3. Animal(String s) იძახებს super() – ს
2. Animal() იძახებს this(„შემთხვევით არჩეული სტრიქონი“)
1. main() იძახებს new Animal() – ს
განვიხილოთ Animal კლასის კოდი:
- ხაზი 2 String ტიპის ეგზემპლარის name ცვლადის აღწერა.
- ხაზები 3-5 კონსტრუქტორი რომელიც ღებულობს String ტიპის პარამეტრს და ანიჭებს მას ეგზემპლარის ცვლადს.
- ხაზი 7 იმ შემთხვევაში თუ კლიენტი (გამომძახებელი კოდი) არ გადასცემს კონსტრუქტორს პარამეტრს, უპარამეტრო კონსტრუქტორი დააგენერირებს სახელს makeRandomName() მეთოდის მეშვეობით.
- ხაზი 8 უპარამეტრო კონსტრუქტორი გამოიძახებს მის გადატვირთულ პარამეტრიან კონსტრუქტორს რომელიც პარამეტრად ღებულობს სტრიქონს. გადატვირთული კონსტრუქტორის გამოძახება ხორციელდება this – ის მეშვეობით, თუმცა ასეთ შემთხვევაში this – ის გამოყენება წააგავს მეთოდესი გამოძახებას this().
- ხაზი 11 აღსანიშნავია რომ makeRandomName() მეთოდი აღწერილია როგორც static. მეთოდი სტატიკური უნდა იყოს გამომდინარე იქიდან რომ შეუძლებელია ეგზემპლარის (არასტატიკური) მეთოდზე ან ცვლადზე კონსტრუქტორიდან მიმართვა იქამდე სანამ სუპერ კონსტრუქტორი არ იქნება გამოძახებული და იგი არ დაამთავრებს შესრულებას, ხოლო რადგან მოცემულ შემთხვევაში სუპერ (super()) კონსტრუქტორის გამოძახება ხდება მე-3 ხაზზე აღწერილი პარამეტრიანი კონსტრუქტორიდან და არა იმ კონსტრუქტორიდან რომელშიც ვიძახებთ makeRandomName() მეთოდს, ამ მეთოდის გამოძახების ერთადერთი საშუალება არის ის თუ მას აღვწერთ როგორც სტატიკურს.
- ხაზი 12 ხდება 0 – სა და 4 – ს შორის არსებული შემთხვევითი მთელი რიცხვის გენერაცია.
- ხაზი 13 იქმნება ახალი String ტიპის ობიექტი. რადგან მეთოდის ამოცანა მდგომარეობს იმაში რომ დააბრუნოს შემთხვევითი მნიშვნელობა სიიდან, აუცილებელია ამ სიის შექმნა. აღნიშნულ სტრიქონში:
- აღიწერება String ტიპის name ცვლადი.
- იქმნება String ტიპის მასივი (ანონიმურად – რადგან ეს მასივი არ ენიჭება რომელიმე ცვლადს).
- ხდება მასივის ელემენტის ამოღება [x] ინდექსით (x ცვლადი აღწერილია მე-12 ხაზზე).
- მასივიდან ამოღებული მნიშვნელობა ენიჭება name ცვლადს.
- ხაზი 18 გამოიძახება უპარამეტრო კონსტრუქტორი (რომელიც თავისთავად იძახებს პარამეტრიან კონსტრუქტორს რომელსაც გადასცემს შემთხვევით მნიშვნელობას)
- ხაზი 20 გამოიძახება გადატვირთული კონსტრუქტორი რომელსაც პარამეტრად გადაეცემა სტრიქონი.
განხილულ მაგალითში საკვანძო ნაწილია მე-8 ხაზი, სადაც super() კონსტრუქტორის ნაცვლად გამოიძახება this(). this() ყოველთვის ნიშნავს სხვა კონსტრუქტორის გამოძახებას იგივე კლასში. რადგან super() კონსტრუქტორის გამოძახება არის გარდაუვალი და აუცილებელი, ხოლო this() იძახებს Animal კლასის პარამეტრიან კონსტრუქტორს, super() გამოძახება მოხდება სწორედ აღნიშნულ პარამეტრიან კონსტრუქტორში.
ყოველივე ზემოთქმულიდან გამომდინარე კონსტრუქტორის პირველი გამოსახულება აუცილებლად უნდა იყოს ან super() ან this() გამოძახება.
ისეთ შემთხვევაში თუ კონსტრუქტორში არ არის არც ერთი super() და this() გამოძახება, კომპილატორი ჩასვავს super() ის უპარამეტრო გამოძახების კოდს.
წინა წესის გათვალისწინებით შეუძლებელია კონსტრუქტორში იყოს ორივე super() და this() გამოძახება. რადგან ერთერთი მათგანის გამოძახება უნდა იყოს პირველი გამოსახულება კონსტრუქტორში, შეუძლებელია მათი ერთდროულად გამოყენება.
ტეგები: Java
[...] დეტალებიც განსხვავდება ჯავას კონსტრუქტორებისაგან და კლასების [...]