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 class – abstract
açar sözü ilə yaradılan classlardır və onların birbaşa obyektini yaratmaq mümkün deyil. Abstract metod – abstract
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əmprivate
- həm
abstract
, həmstatic
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:
- Abstract classın
new
ilə birbaşa obyekti yaradıla bilməz; - Abstract classda istənilən sayda (və ya heç bir) abstract və yaxud abstract olmayan metod tanımlana bilər;
- Abstract classlar
private
və yafinal
ola bilməz (burada söhbət top-level classlardan gedir); - Abstract class başqa bir abstract classı
extends
edirsə, onun bütün abstract metodlarını öz şəxsi abstract metodları kimi varis alır; - 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:
- Abstract metodlar ancaq abstract classda tanımlana bilər;
- Abstract metodlar
private
,final
və yaxudstatic
elan edilə bilməz; - Abstract classda elan edilmiş abstract metodların gövdəsi olmamalıdır;
- Abstract metodların subclassda override edilməsi qaydaları adi metodların override edilməsi qaydaları ilə eynidir.
[topics lang=az]