OCA Java imtahan mövzuları

Abstract Class

Creating Abstract Classes

Abstract classlar bizə nə üçün lazım ola bilər?

Tutaq ki, bizim Animal classımız var və onun daxilində bir neçə metod mövcuddur. Biz istəyirik ki, Animal classını varis alan (extends edən) bütün classlar getName() metodunu mütləq override etsinlər. Bu zaman bizim köməyimizə abstract class və abstract metodlar gəlir. Abstract classabstract açar sözü ilə yaradılan classlardır və onların birbaşa obyektini yaratmaq mümkün deyil. Abstract metodabstract açar sözü ilə yaradılan metodlardır və bu metodların gövdəsi olmur.

abstract class Animal {

    protected int age;
    
    public abstract String getName();

    public void eat() {
        System.out.println("Animal is eating");
    }
}

public class Dog extends Animal {

    public String getName() {
        return "dog";
    }
}

 

Defining an Abstract Class

Abstract classın daxilində abstract olmayan (nonabstract) metod və dəyişənlər də təyin etmək mümkündür. Maraqlı səslənsə də bu doğrudur ki, abstract classın daxilində ümumiyyətlə abstract metod olmaya da bilər, yəni elə bir məcburiyyət yoxdur ki, abstract classın daxilində mütləq hər hansı bir abstract metod olmalıdır. Amma abstract metod ancaq abstract classda tanımlana (define) bilər, adi classda icazə verilmir:

abstract class Rabbit {}    // everything is ok

class Puppy {
    public abstract void bark();   // DOES NOT COMPILE
}

Mövzunun əvvəlində də qeyd etdik ki, abstract metodlar gövdəsiz olurlar, əks halda compile xətası verir:

public abstract class Turtle {

    public abstract void swim() {}   // DOES NOT COMPILE

    public abstract int getAge() {   // DOES NOT COMPILE
        return 15;
    }
}

Abstract class final ola bilməz! Çünki abstract classı birbaşa obyektini yaratmaqla istifadə etmək mümkün deyil, ancaq başqa class tərəfindən extends edilməklə istifadə edilə bilər. Onu final təyin etməklə isə artıq bildiririk ki, bu class varis alına, yəni extends edilə bilməz. Ona görə də compiler classın eyni zamanda həm abstract, həm də final olduğunu gördükdə xəta verir:

public final abstract class Tortoise {}   // DOES NOT COMPILE

Eləcə də, abstact metodlar final ola bilməz. Çünki abstract metodlar mütləq override olunmalıdır, final olduqda isə override edilməyə icazə vermir və bu səbəbdən conflict yaranır. Həmçinin bənzər səbəblərə görə metod eyni zamanda

  • həm abstract, həm private
  • həm abstract, həm static

ola bilməz:

public abstract class Goat {

    public abstract final void chew();  // DOES NOT COMPILE

    private abstract void eat();        // DOES NOT COMPILE

    static abstract void walk();        // DOES NOT COMPILE
}

Gündəlik praktikada aşağıdakı formada kod nümunəsinə rast gəlməyəcəksiniz, amma sadəcə bilmək yaxşı olardı ki, bu formada yazılış compile xətası vermir:

public abstract class Calculator {

    abstract void calculate();

    public static void main(String[] args) {
        System.out.println("calculating");
        Calculator x = null;
        x.calculate(); //does compile, but throws NullPointerException in runtime
    }
}

 

Creating a Concrete Class

Qeyd etdik ki, abstract classların birbaşa obyektini yaratmaq mümkün deyil, compile xətası verir:

public abstract class Cat {

    public static void main(String[] args) {
        final Cat cat = new Cat();   // DOES NOT COMPILE
    }
}

Abstract classların istifadəsi o zaman faydalı olur ki, onlar konkret subclasslar tərəfindən varis alınsın (extends edilsin). Konkret class (concrete class) – abstract classı extends edən birinci abstract olmayan subclassdır (first nonabstract subclass) və bütün abstract metodları override etməyi tələb edir:

public abstract class Animal {
    public abstract String getName();
}

class Tiger extends Animal {}  // DOES NOT COMPILE

Tiger birinci konkret subclassdır və ona görə də getName() metodunu override etməlidir.

Elə hal ola bilər ki, birinci konkret class yox (bu nümunədə Tiger), bu konkret classın özünü extends edən digər bir konkret class abstract metodu (bu nümunədə getName()) override etsin. Amma bu halda da compile xətası verəcək, çünki istənilən halda ancaq birinci konkret subclass abstract metodları override etməlidir:

public abstract class Animal {
    public abstract String getName();
}

class Tiger extends Animal {}  // DOES NOT COMPILE

class TigerCub extends Tiger {
    public String getName() {
        return "tiger-cub";
    }
}

 

Extending an Abstract Class

Əvvəlki mövzuda yazdığımız kodda kiçik bir dəyişiklik etsək, fərqli nəticə ala bilərik:

public abstract class Animal {
    public abstract String getName();
}

class Tiger extends Animal {}  // DOES NOT COMPILE

abstract class Lion extends Animal {}

Nümunədən də göründüyü kimi əgər abstract class digər abstract classı extends edirsə, onun abstract metodlarını override etmək məcburiyyətində deyil, artıq istəyə bağlıdır. Amma override etməsə belə, istənilən halda həmin abstract metodları varis alır və bu abstract metodun özünü extends edən ilk konkret subclass artıq hər iki absract classın abstract metodlarını override etməyə məcburdur:

abstract class Animal {
    public abstract String getName();
}

abstract class BigCat extends Animal {
    public abstract void roar();
}

public class Lion extends BigCat {

    public String getName() {
        return "Lion";
    }

    public void roar() {
        System.out.println("roar");
    }
}

Amma bu qaydanın özündə də bir istisna var. Əgər ortadakı abstract class (bizim nümunədə BigCat) birinci abstract classdakı abstract metodu (bizim nümunədə getName()) override edərsə, o zaman artıq birinci konkret subclassdan həmin metodu override etmək tələb olunmayacaq. Çünki subclass artıq həmin metodu abstract metod kimi yox, konkret metod kimi qəbul edəcək.

abstract class Animal {
    public abstract String getName();
}

abstract class BigCat extends Animal {
    public String getName() {
        return "BigCat";
    }

    public abstract void roar();
}

public class Lion extends BigCat {
    public void roar() {
        System.out.println("roar");
    }
}

 

Bütün bu qeyd etdiklərimizi yekunlaşdıraraq aşağıdakı nəticəyə gələ bilərik;

 

Abstract Class Defination Rules:

  1. Abstract classın new ilə birbaşa obyekti yaradıla bilməz;
  2. Abstract classda istənilən sayda (və ya heç bir) abstract və yaxud abstract olmayan metod tanımlana bilər;
  3. Abstract classlar private və ya final ola bilməz (burada söhbət top-level classlardan gedir);
  4. Abstract class başqa bir abstract classı extends edirsə, onun bütün abstract metodlarını öz şəxsi abstract metodları kimi varis alır;
  5. Abstract classı extends edən birinci konkret subclass həmin abstract classın bütün abstract metodlarını override etməlidir.

 

Abstract Method Defination Rules:

  1. Abstract metodlar ancaq abstract classda tanımlana bilər;
  2. Abstract metodlar private, final və yaxud static elan edilə bilməz;
  3. Abstract classda elan edilmiş abstract metodların gövdəsi olmamalıdır;
  4. Abstract metodların subclassda override edilməsi qaydaları adi metodların override edilməsi qaydaları ilə eynidir.

 

[topics lang=az]

About the author

Mushfiq Mammadov

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.