1. İnterfeyslərlə tanışlıq
Bugün sanki bilik günü. Daha bir yeni və maraqlı mövzu — interfeyslər.
İnterfeys — Abstraksiya və Polimorfizmin "uşağıdır". İnterfeys çox oxşayır abstrakt sinfə, hansının ki, bütün metodları abstraktdır. O, sinif kimi elan edilir, amma interface
açar sözü istifadə olunur.
interface Pişiklər
{
void mırıldamaq();
void miyavlamaq();
void nərildəmək();
}
İnterfeyslərlə bağlı bir neçə faydalı fakt:
1. İnterfeysin elan edilməsi
interface Drawable
{
void draw();
}
interface HasValue
{
int getValue();
}
class
sözü yerinəinterface
yazırıq.- Yalnız abstrakt metodlar ehtiva edir (
abstract
sözünü yazmaq lazım deyil) - Əslində interfeyslərin bütün metodları
public
-dur
İnterfeys yalnız interfeyslərdən miras alına bilər. Amma interfeysin bir çox valideyni ola bilər. Həm də deyirlər ki, Java-da interfeyslərin çoxsaylı mirası var. Misallar:
interface Element extends Drawable, HasValue
{
int getX();
int getY();
}
3. Siniflərin interfeyslərdən miras alması
Sinif bir neçə interfeysdən miras ala bilər (və yalnız bir sinifdən). Bunun üçün implements
açar sözü istifadə olunur. Misal:
abstract class ChessItem implements Drawable, HasValue
{
private int x, y, value;
public int getValue()
{
return value;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
}
ChessItem sinfi abstrakt elan edilmişdir: o, bütün miras alınan metodları reallaşdırdı, draw
istisna olmaqla. Yəni ChessItem
sinfi bir abstrakt metodu ehtiva edir — draw()
.
Texniki olaraq extends
və implements
sözlərinin arasında heç bir fərq yoxdur: hər ikisi miraslamadır. Bu, kodun oxunurluğunu artırmaq üçün belə edilmişdir. İngilis dilində qəbul olunmuşdur ki, siniflər miras alınır (extends
), interfeyslər isə reallaşdırılır (implements
).
4. Dəyişənlər
Və ən önəmlisi: interfeyslərdə dəyişənlər elan etmək olmaz (statiklərdən başqa).
Bəs interfeyslər niyə lazımdır? Onlardan nə zaman istifadə olunur? İnterfeyslərin siniflərə nisbətən iki güclü üstünlüyü var, hansılara ki, sonrakı hissələrdə baxacağıq.
2. "Metodların təsviri"ni onların realizasiyasından ayırmaq.
Əvvəllər artıq danışmışdıq ki, əgər istəyirsinizsə, digər siniflərdən sinfinizin metodlarını çağırmağa icazə verilsin, onları public
açar sözü ilə işarələmək lazımdır. Əgər istəyirsinizsə ki, bəzi metodlar yalnız həmin sinifdə istifadə olunsun, onları private
açar sözü ilə işarələmək lazımdır. Başqa sözlə, sinfin metodlarını iki kateqoriyaya bölürük: «hamı üçün» və «yalnız özümüz üçün».
İnterfeyslərin köməyi ilə bu bölgünü daha da gücləndirə bilərik. Biz xüsusi bir «sinif hamı üçün» və ikinci bir «sinif yalnız özümüz üçün» yaradacağıq, hansı ki, birincidən miras alınacaq. Bu təxminən belə olacaq:
Əvvəl | Sonra |
---|---|
|
|
|
|
Sinfimizi iki yerə böldük: interfeys və sinif, interfeysdən miras alınmış sinif. Bəs üstünlük haradadır?
Eyni interfeysi müxtəlif siniflər reallaşdıra bilər (miras ala bilər). Hər birində isə müxtəlif davranış ola bilər. Eynilə ArrayList
və LinkedList
— List
interfeysin iki fərqli reallaşdırılmasıdır.
Beləliklə, biz yalnız müxtəlif reallaşdırmaları deyil, həmçinin həmin reallaşdırmaları saxlayan sinfi də gizlədə bilərik (kodda yalnız interfeys işlənə bilər). Bu isə proqram icra olunarkən (runtime zamanı) bir obyektləri digərləri ilə əvəz etməyə, obyektin davranışını onu istifadə edən bütün siniflərdən gizli saxlamağa imkan verir.
Bu, polimorfizm ilə birlikdə çox güclü texnologiyadır. Hal-hazırda bu qədər zəruri görünməyə bilər. Əvvəlcə onlarca və ya yüzlərlə sinifdən ibarət proqramlarla işləməlisiniz ki, interfeyslərin həyatı necə asanlaşdırdığını başa düşəsiniz.
3. Çoxlu irsiyyət
Java-da bütün siniflər yalnız bir ana sinifə sahib ola bilər. Digər proqramlaşdırma dillərində siniflər tez-tez bir neçə ana sinifə sahib ola bilər. Bu çox rahatdır, amma eyni zamanda bir çox problemlər gətirir.
Java-da kompromis əldə ediblər: siniflərin çoxlu irsiyyətini qadağan ediblər, lakin interfeyslərin çoxlu irsiyyətinə icazə veriblər. İnterfeys bir neçə interfeys-ana əldə edə bilər. Sinif bir neçə interfeys-ana əldə edə bilər, lakin yalnız bir sinif-ana ola bilər.
Bəs niyə siniflərin çoxlu irsiyyəti qadağan edilib, interfeyslərin yox? Bütün məsələ piramidal irsiyyətdədir:

Sinif B, sinif A-dan irsi olduqda, sinif C və D haqqında heç nə bilmir. Buna görə də o, sinif A-nın dəyişənlərini lazım olduğu kimi istifadə edir. Sinif C də eyni şeyi edir: sinif A-nın dəyişənlərini fərqli bir şəkildə istifadə edir. Və sinif D-də bu, bir münaqişəyə çevrilir.
Gəlin belə sadə bir nümunəni nəzərdən keçirək. Tutaq ki, bizim 3 sinifimiz var:
class Data
{
protected int value;
}
class XCoordinate extends Data
{
public void setX (int x) { value = x;}
public int getX () { return value;}
}
class YCoordinate extends Data
{
public void setY (int y) { value = y;}
public int getY () { return value;}
}
Data sinifi özündə value
dəyişənini saxlayır. Onun varisi olan XCoordinate sinifi onu x
dəyişənini saxlamaq üçün istifadə edir, YCoordinate sinifi isə onu y
dəyişənini saxlamaq üçün istifadə edir.
Və bu işləyir. Ayrı-ayrılıqda. Amma əgər biz XYCoordinates sinifini hər iki sinifdən – XCoordinate
və YCoordinate
– irsi etmək istəsək, işləməyən kod alacağıq. Bu sinifdə valideyn siniflərinin metodları olacaq, amma onlar düzgün işləməyəcək, çünki value
dəyişəni yalnız birdir.
İnterfeyslərə dəyişənlərə sahib olmağı qadağan etdikləri üçün bu cür bir münaqişə onlarda ola bilməz. Buna görə interfeyslərin çoxlu irsiyyətinə icazə verilir.
GO TO FULL VERSION