OCA Java imtahan mövzuları

Constructor Rules. super() vs this()

Defining Constructors

Javada hər constructorda birinci ifadə (first statement) ya class daxilində olan başqa bir constructoru çağırır (this() ilə) və yaxud da birbaşa parent classın constructorunu çağırır (super()ilə). Əgər parent constructor arqument qəbul edirsə, super() constructor da müvafiq olaraq arqument qəbul edəcək.

public class City {

    private int population;

    public City(int population) {
        super();    // line 1   
        this.population = population;
    }
}

class Baku extends City {

    public Baku(int population) {
        super(population);   // line 2   
    }

    public Baku() {
        this(2_181_800);  // line 3   
    }
}

line 1java.lang.Object classında təyin edilmiş parent constructoru çağırır.

line 2City classının parametr qəbul edən constructorunu çağırır.

line 3super() çağırılmır, əvəzində həmin classın digər constructoru çağırılır.

*line 3`ə əsasən bu qənaətə gəlmək olar ki, əgər this() varsa çox güman super() ignore olunur, çünki default olaraq tək super() çağırsa bu compile olunmamalıdı, çünki parent classda default constructor “omit” olunur.

super() this() kimi constructorun ancaq birinci ifadəsi (first statement) olaraq çağırıla bilər, əks halda compile xətası verir.

Əgər parent classda birdən artıq constructor mövcuddursa, child class bu constructorlardan istənilən hər hansı birini istifadə edə bilər:

class Animal2 {

    private int age;
    private String name;

    public Animal2(int age, String name) {
        super();
        this.age = age;
        this.name = name;
    }

    public Animal2(int age) {
        super();
        this.age = age;
        this.name = null;
    }
}

class Gorilla extends Animal2 {

    public Gorilla(int age) {
        super(age, "Gorilla");
    }

    public Gorilla() {
        super(4);
    }
}

Child classın tək parametrli constructoru parent classın iki parametrli constructorunu, parametrsiz constructoru isə parent classın bir parametrli constructorunu çağırır. Yəni child constructor uyğun parent constructoru çağırmağı tələb etmir.

 

 

Understanding Compiler Enhancements

İndiyə kimi baxdığımız classların çoxunda parent constructor super() açar sözü ilə aşkar şəkildə çağırılmırdı, bəs sual oluna bilər ki, belə olan halda bəs kod necə compile olunur? Çünki, əgər parent constructor aşkar şəkildə çağırılmayıbsa, java compiler avtomatik olaraq super() ifadəsini əlavə edir. Aşağıdakı classların üçü də bir-biri ilə ekvivalentdir:

public class Room {
}

public class Room {
    public Room() { }
}

public class Room {
    public Room() {
        super();
    }
}

Bəs parent classın parametrsiz constructoru olmadıqda nə baş verəcək? Bu zaman java compiler bizə kömək etməyəcək, bu halda biz mütləq child classda ən azı bir constructor yaratmalıyıq və həmin constructor parent constructoru super() ilə aşkar şəkildə çağırmalıdır. Əks halda compile xətası verəcək:

class Mammal {
    public Mammal(int age) { }
}

class Elephant extends Mammal {   // DOES NOT  COMPILE
}

Yuxarıda qeyd etdiyimiz kimi child classda ən azı bir constructor yaratmalıyıq:

class Elephant extends Mammal {
    public Elephant() {   // DOES NOT COMPILE
    }
}

Compiler yaratdığımız bu child constructorun ilk sətrinə super() əlavə etməyə cəhd edir, amma görür ki, parent classda uyğun constructor yoxdur. Ona görə də biz parametrli super() ifadəsini aşkar şəkildə əlavə etməklə ancaq problemi aradan qaldıra bilərik:

class Elephant extends Mammal {
    public Elephant() {
        super(7);
    }
}

Enthuware sualları içərisində bu mövzu ilə bağlı maraqlı sual nümunələri var, onlardan birinə baxaq:

class A {
    int i;
    public A(int x) {
        this.i = x;
    }
}

class B extends A {
    int j;
    public B(int x, int y) {
        super(x);
        this.j = y;
    }
}

Sualda soruşulur ki, aşağıdakı constructorlardan hansını B classına əlavə etsək, kod xətasız compile olunar?

a) B() { }
b) B(int y) { j = y; }
c) B(int y) { super(y*2); j = y; }
d) B(int y) { j = y; j = y*2; }
e) B(int z) { this(z, z); }

Sualda iki düzgün cavab bəndi var. Az öncə yuxarda qeyd etdiyimiz qaydaları bu suala tətbiq etməklə düzgün cavabları rahatlıqla tapmaq mümkündür. Çalışın özünüz tapmağa cəhd edəsiniz. Əgər çətinlik yaranarsa çəkinmədən kommentdə yaza bilərsiniz.

Öz real imtahan təcrübəmdən deyə bilərdim ki, ən çox soruşulan mövzulardan biri bu mövzudur, ona görə də bu mövzuya xüsusi diqqət ayırmaq lazımdır.

 

 

Reviewing Constructor Rules

Yuxarıda dediyimiz qaydaları aşağıdakı şəkildə ümumiləşdirə bilərik:

1. Hər constructorun ilk ifadəsi ya this() açar sözündən istifadə edərək class daxilindəki digər constructoru çağırır, ya da super() açar sözündən istifadə edərək birbaşa parent classın constructorunu çağırır.

2. super()this() ancaq constructorun birinci ifadəsi (first statement) olmalıdır, əks halda xəta verir.

3. Əgər super() constructorda aşkar şəkildə əlavə edilməzsə, Java constructorun ilk sətrinə arqumentsiz super() ifadəsini əlavə edəcək.

4. Əgər parent classın parametrsiz constructoru yoxdursa və child classda hər hansı bir constructor yaradılmayıbsa, compiler xəta verəcək və arqumentsiz default constructoru (default no-argument constructor) child classa əlavə etməyə cəhd edəcək.

5. Əgər parent classın parametrsiz constructoru yoxdursa, compiler hər child constructorda parent constructoru aşkar şəkildə çağırmağı tələb edir.

 

[topics lang=az]

About the author

Mushfiq Mammadov

2 Comments

  • Salam Mushfiq bey, necesiz, insAllah ki yaxsisiz. Bu gozel islere gore derin tesekkurumu bildirirem, heqiqeten de notlar eladi, cox faydali oldu, ellerivize sagliq. Bir sualim olacaqdi men de OCA imtahanina hazirlasiram, bu sual basa dusmekde biraz eziyyet cekirem, ona gore sorusmaq istedim:

    class A {
    int i;
    public A(int x) {
    this.i = x;
    }
    }

    class B extends A {
    int j;
    public B(int x, int y) {
    super(x);
    this.j = y;
    }
    }

    a) B() { }
    b) B(int y) { j = y; }
    c) B(int y) { super(y*2); j = y; }
    d) B(int y) { j = y; j = y*2; }
    e) B(int z) { this(z, z); }

    Cavablarin niye C ve E olmagini basa dusmedim 🙁

    • Salam. Dəyməz buyurun, xoş sözlərinizə görə çox sağ olun. Faydalı olmasına sevindim.

      Məqaləyə təkrar diqqətlə nəzər yetirsəniz, cavabını özünüz də rahatlıqla tapa biləcəksiniz. Orada belə bir paraqraf var:

      “Compiler yaratdığımız bu child constructorun ilk sətrinə super() əlavə etməyə cəhd edir, amma görür ki, parent classda uyğun constructor yoxdur. Ona görə də biz parametrli super() ifadəsini aşkar şəkildə əlavə etməklə ancaq problemi aradan qaldıra bilərik”.

       
      Bu sualda da həmin məsələdir. Əgər konstruktorun ilk sətrinə super() yaxud this() ifadələrindən heç birini aşkar şəkildə yazmamısınızsa, compiler avtomatik olaraq ilk sətirə super() əlavə edir. Diqqət etdinizsə, A classında parametrsiz konstruktor yoxdur. super() isə parent classda (yəni A classında) parametrsiz konstruktoru axtarır, tapmadıqda compile xətası verir.

      A, BD bəndlərində ilk sətirə qeyd etdiyimiz ifadələrdən heç biri əlavə edilmədiyinə görə default olaraq super() əlavə edilir. O da gedib parametrsiz konstruktoru tapmadığına görə compile xətası verir. Bu səbəbdən bu cavablar yanlışdır. Qalır CE.

      C bəndində super(y*2); ilə aşkar şəkildə A(int x) konstruktoru çağırılır. E bəndində isə this(z, z); ilə B(int x, int y) konstruktoru çağırılır. O da öz daxilində super(x);-i çağırdığına görə problem yaranmır. Əgər this() istifadə edilibsə, o zaman super() ignore edilir. Bu səbəblərdən dolayı CE normal compile olunur.

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.