1. Bütün siniflər Object
-dən miras alır
Java-da bütün siniflər dolayısı ilə (gizli şəkildə) Object
sinifindən miras alır.
Mirasın nə olduğunu və Java-da necə işlədiyini Java Core bölməsində öyrənəcəyik. İndisə bundan çıxan sadə bir faktı nəzərdən keçirək:
Object
tipində olan dəyişənə istənilən sinifdən bir obyekt mənimsətmək olar. Məsələn:
Kod | Qeydlər |
---|---|
|
o dəyişənində Scanner tipində obyektin istinadını saxlayır |
|
o dəyişənində String tipində obyektin istinadını saxlayır |
|
o dəyişənində Integer tipində obyektin istinadını saxlayır |
|
o dəyişənində String tipində obyektin istinadını saxlayır |
Burada yaxşı xəbərlər bitir. Kompilyator nəzarət etmir, hansı tipdə obyekt Object
tipində dəyişəndə saxlanılıb, buna görə də saxlanılmış obyektin olan metodlarını, ancaq Object
tipində dəyişənin metodlarını çağırmaq olmaz.
Əgər belə obyektin metodlarını çağırmaq lazımdırsa, onda əvvəlcə onun istinadını düzgün tipdə dəyişəndə saxlamaq, sonra isə həmin dəyişəndə metodları çağırmaq lazımdır:
Kod | Qeydlər |
---|---|
|
Proqram kompilyasiya edilmir. Object sinfində nextInt() metodu yoxdur. |
|
Bu halda işləyəcək. Burada biz Scanner tipində obyektin istinadını Scanner tipində dəyişəndə saxlayırıq tipin çevrilməsi operatoru vasitəsilə. |
Object
tipində dəyişəni Scanner tipinə mənimsətmək sadəcə belə mümkün deyil, hətta əgər Object
tipində dəyişəndə Scanner
tipində obyekt saxlanılırsa belə. Amma bu, sizə artıq məlum olan tipin çevrilməsi operatoru ilə mümkün ola bilər. Ümumi halda bu, belə görünür:
Tip ad1 = (Tip) ad2;
Burada ad1
– Tip
tipində dəyişənin adı, ad2
– bu isə Object
tipində dəyişənin adı, hansında ki, Tip
tipində obyektin istinadı saxlanılır.
Tip çevrilməsi
Əgər dəyişən və obyektin tipləri fərqlidirsə, ClassCastException
xəta baş verəcək. Məsələn:
Kod | Qeydlər |
---|---|
|
İcra zamanı xəta baş verəcək: burada ClassCastException atılacaq |
Java-da bu xətanın qarşısını almağın yolu var: dəyişən daxilində hansı tipin olduğunu yoxlamağın üsulu mövcuddur:
ad instanceof Tip
instanceof
operatoru yoxlayır, müəyyən edir ki, ad
dəyişəni, Tip
tipində bir obyekt olub-olmadığını.
Məsələn — məlumatlar massivində sətri tapmaq:
Kod | Qeydlər |
---|---|
|
Autoboxing bu dəyərləri Integer , String və Double -a çevirir.Obyektlər massivində dövr Əgər obyekt String tipində olarsaOnu String tipində dəyişəndə saxlayırıqDəyişəni ekrana çap edirik. |
2. Şablonların yaranma səbəbi (kolleksiyalar)
Kolleksiyalara qayıdırıq.
Java proqramçıları ArrayList
sinfini yaratmağa başladıqda, onu universal etmək istəyirdilər ki, istənilən tipdə obyektləri orada saxlamaq mümkün olsun. Buna görə elementləri saxlamaq üçün Object
tipli massivdən istifadə etdilər.
Belə yanaşmanın güclü tərəfi odur ki, kolleksiyaya istənilən tipdə obyekt əlavə edilə bilər.
Bəs zəif tərəfləri? Bir neçə belə zəif cəhət dərhal görünür.
Çatışmazlıq 1.
Kolleksiyadan elementləri çıxararkən hər zaman tip çevirmə operatorundan istifadə etmək lazım idi:
Kod | Qeyd |
---|---|
|
Obyektləri Object tipinə aid referensləri saxlamaq üçün kolleksiya yaradırıq.Kolleksiyanı 10 , 20 , ... 100 rəqəmləri ilə doldururuq;Kolleksiyanın elementlərini cəmləyirik Tip çevirmədən istifadə olunmalıdır |
Çatışmazlıq 2.
Kolleksiyadakı elementlərin müəyyən bir tipdə olacağına zəmanət yox idi
Kod | Qeyd |
---|---|
|
Obyektləri Object tipinə aid referensləri saxlamaq üçün kolleksiya yaradırıq.Kolleksiyanı Double tipində rəqəmlərlə doldururuq:0.0 , 2.5 , 5.0 , ...Kolleksiyanın elementlərini cəmləyirik Xəta olacaq: Double tipini Integer tipinə çevirə bilməzsiniz |
Kolleksiyaya məlumatlar hər hansı bir yerdən doldurula bilər:
- başqa bir metodda
- başqa bir proqramda
- fayldan yüklənərək
- şəbəkədən alınaraq
Çatışmazlıq 3.
Kolleksiyanın məlumatlarını bilməyərəkdən dəyişmək mümkündür.
Siz öz məlumatlarınızla doldurduğunuz kolleksiyanı hər hansı metodun içərisinə ötürə bilərsiniz, lakin həmin metod, hansı ki başqa bir proqramçı tərəfindən yazılıb, sizin kolleksiyanıza öz məlumatlarını əlavə edə bilər.
Kolleksiyanın adına baxaraq hansı tipdə məlumatların saxlanıldığını anlamaq mümkün deyil. Hətta dəyişkənə belə bir ad versəniz belə, ona referens ötürərək onlarla metoda göndərmək olar və orada dəyişkənin ilkin adı haqqında heç bir məlumat olmaz.
3. Generics
Java-da Generics (Generics) kimi gözəl bir şey bütün bu problemləri həll edir.
Java-da generics dedikdə, tiplərə parametr-tiplər əlavə etmək imkanı nəzərdə tutulur. Bu yolla mürəkkəb birləşmiş tiplər əmələ gəlir. Belə bir birləşmiş tip ümumi halda belə görünür:
ƏsasTip<TipParametr>
Hər şey birlikdə — bu məhz tipdir. Və o, adi halda tiplərin istifadə oluna biləcəyi yerlərdə istifadə oluna bilər.
Kod | Təsvir |
---|---|
|
Dəyişənlərin yaradılması |
|
Obyektlərin yaradılması |
|
Massivlərin yaradılması |
Belə bir kolleksiyaya yalnız Integer
tipində dəyişənlər saxlamaq olar:
Kod | Təsvir |
---|---|
|
ArrayList tipi ilə kolleksiya, elementləri Integer tipindədirBelə edə bilərsən Və belə də olar: işləyəcək
autoboxing
Amma belə olmaz: kompilyasiya xətası |
Parametr-tipləri olan öz siniflərinizi necə yaratmağı Java Collections missiyasında öyrənəcəksiniz. İndi isə bunun necə istifadə edildiyini və necə işlədiyini nəzərdən keçirəcəyik.
4. Generics necə işləyir
Əslində Generics çox primitiv şəkildə işləyir.
Compiler sadəcə parametrli tipi elə həmin tipə çevirir, yalnız parametrlərsiz. Onun metodları ilə qarşılıqlı əlaqədə isə tipi parametrə çevirmə əməliyyatı əlavə edir:
Kod | Compiler nə edəcək |
---|---|
|
|
|
|
|
|
|
|
Tutaq ki, bizdə tam ədədlər kolleksiyasındakı ədədləri toplayan metodun kodu var idi:
Kod | Compiler nə edəcək |
---|---|
|
|
Yəni mahiyyətcə generics — autoboxing kimi sintaktik şəkər növüdür, yalnız bir az daha böyükdür. Autoboxing-də compiler bizdən int tipini Integer-ə və əksinə çevirmə metodlarını əlavə edir, generics üçün isə tip çevirmə operatorlarını əlavə edir.
Compiler sizin kodunuzu generics ilə compile etdikdən sonra, içində parametrli tipli bütün siniflər sadəcə siniflərə və tip çevirmə operatorlarına çevrilmiş olur. Başlanğıcda mürəkkəb tipli dəyişənlərin hansı tip-parametrdə olduğu məlumatı itir. Bu effektə bəzən tiplərin silinməsi də deyirlər.
Bəzən öz parametrli tipləri olan siniflərini yazan proqramçılara ora parametr kimi ötürülən tiplər haqqında məlumat çox lazım olur. Bununla necə mübarizə aparıldığını və nəticədə nə baş verdiyini Java Collections mövzusunda öyrənəcəksiniz.
5. Generics haqqında bir neçə məqam
Generics haqqında maraqlı faktlar.
Siniflərin yalnız bir deyil, bir neçə tip parametri ola bilər. Təxminən belə görünür:
ƏsasTip<TipParametr1, TipParametr2, TipParametr3>
Əslində, bu heç də təəccüblü deyil. Kompilyator bir tipə cast operatoru əlavə edə bildiyi yerdə, bir neçə də əlavə edə bilər.
Nümunələr:
Kod | İzah |
---|---|
|
put metodunun birinci parametri Integer tipindədir, ikinci isə String tipindədir |
Bundan əlavə, mürəkkəb tiplər də parametr kimi istifadə edilə bilər. Təxminən belə görünür:
ƏsasTip<TipParametr<TipParametrParametri>>
Gəlin təsəvvür edək ki, biz bir siyahı yaratmaq istəyirik, həmin siyahı da string-lərdən ibarət siyahıları saxlayır. Belə bir kod alarıq:
// salamlaşmalar siyahısı
ArrayList<String> listHello = new ArrayList<String>();
listHello.add("Salam");
listHello.add("Hi");
// vidalaşmalar siyahısı
ArrayList<String> listBye = new ArrayList<String>();
listBye.add("Hələlik");
listBye.add("Good Bye");
// siyahılar siyahısı
ArrayList<ArrayList<String>> lists = new ArrayList<ArrayList<String>>();
lists.add(listHello);
lists.add(listBye);
GO TO FULL VERSION