Nümunə 1:
class X { public String print() { return "X"; } } class Y extends X { // public String print() { return "Y"; } } class Z extends Y { // public String print() { return "Z"; } } class A extends Z {} class Main { public static void main(String[] args) { System.out.println(new A().print()); // prints X } }
Əgər Y
classındakı print()
metodunu kommentdən çıxarsaq Y
çap ediləcək, Z
classındakı print()
metodunu kommentdən çıxarsaq isə Z
çap ediləcək.
Nümunə 2:
Aşağıdakı kodun output`u nə olacaq?
interface Inf1 { int method1(); } interface Inf2 { boolean method2(); } class Test implements Inf1, Inf2 { public int method1() { return 7; } public boolean method2() { return true; } public static void main(String[] args) { Object obj = new Test(); Inf1 i1 = (Inf1) obj; Inf2 i2 = (Inf2) obj; System.out.print(i1.method1()); System.out.print(i2.method2()); } }
Bu cür sual nümunələri mənə görə “Chapter 5” üzrə ən çətin sual nümunələri hesab edilə bilər. Əgər işin içinə “downcasting” daxil oldusa, o zaman diqqətli olmaq lazımdır. Bu nümunədə ilk öncə compile xətasının olub-olmaması yoxlanılmalıdır. Əgər görsək ki, hər şey qaydasındadır, kod compile olunur, o zaman runtime vaxtı exception`un baş verib verməyəcəyi araşdırılmalıdır. Əgər bu dəfə də hər şey qaydasında olarsa, o zaman print ifadədə nə çap ediləcək ona baxılmalıdır.
Main metoda keçməzdən öncə baxmalıyıq ki, Test
classı Inf1
və Inf2
interface`lərinin abstract
metodlarını override edibmi?
Abstract metodlar override edilib. Artıq main metoda keçə bilərik. 11-ci sətirdə problem yoxdur, çünki bütün classlar Object
classından törəmədir. Burada “upcasting” baş verir və Test
classının instansı obj
referansına mənimsədilir. 12 və 13-cü sətirlərdə diqqətli olmaq lazımdır, çünki burada downcasting baş verir (əslində buna tam olaraq downcasting də demək olmur, çünki interface`lər Object
classından törəmirlər). Downcasting zamanı həm kodun compile olunması, həm də runtime vaxtı ClassCastException
`un baş verə bilmə ehtimalı – hər ikisi yoxlanılmalıdır.
Object
classını interface`ə cast etmək mümkündür, buna görə də 12 və 13-cü sətirlər compile xətası vermir. obj
referansı özündə Test
classının instansını saxladığından və Test
classı da Inf1
və Inf2
interface`lərini implements etdiyindən bu sətirlər runtime vaxtı ClassCastException
verməyəcək. Deməli, kod həm normal compile olunur, həm də runtime vaxtı exception vermir. Və kodu run etdikdə 7true
ifadəsi çap edilir.
Nümunə 3:
interface Behaviour {} abstract class Parent { public int age; } class Child extends Parent implements Behaviour {} class Main { public void test(Parent parent) { System.out.println(parent.age); } public static void main(String[] args) { new Main().test(_____); } }
Boş (blank) hissəyə aşağıdakı bəndlərdən hansılar əlavə edildikdə kod compile olunacaqdır?
A. new Parent()
B. new Child()
C. new Behaviour()
D. (Parent)new Object()
E. (Parent)new String()
F. null
Bu da maraqlı kod nümunəsidir, sualla bağlı bilməli olduğunuz bütün nüanslar Chapter 5`in daxilində verilib. Əgər çətinlik çəksəniz, yaxşı olar ki, mövzunu yenidən oxuyasınız.
Nümunə 4:
package objects; public class Car { protected void start(){} void stop(){} }
package car; import objects.*; public class Kia extends Car { public static void main(String[] args) { Kia k = new Kia(); k.start(); k.stop(); Car c = new Kia(); c.start(); c.stop(); } }
Kia
classında hansı sətirlər compile xətası verir?
A. 5
B. 6
C. 7
D. 8
E. 9
F. 10
Sualın cavabı C, E və F bəndləridir. Siz isə səbəbini tapmağa çalışın. Bu sual ilə bağlı bilməli olduğunuz ən vacib fakt mövzunun daxilində izah edilib. Əgər həmin faktı xatırlamasanız, mövzuya təkrar bir də nəzər salın.
Nümunə 5:
abstract class Grandma { public abstract int getAge(); } abstract class Grandpa { public int getAge(); } abstract interface Walk {} class Grandchild extends Grandma, Grandpa implements Walk { int getAge() { return 3; } }
Yuxarıdakı kod nümunəsi ilə bağlı aşağıdakı fikirlərdən hansılar doğrudur?
A. Kod heç bir xəta baş vermədən compile olunur.
B. 2-ci sətirdə compile xətası baş verir.
C. 6-cı sətirdə compile xətası baş verir.
D. 11-ci sətirdə compile xətası baş verir.
E. 12-ci sətirdə compile xətası baş verir.
F. Kod compile olunur amma runtime vaxtı exception baş verir.
Kod nümunəsində OOP-nin ən vacib prinsiplərindən biri pozulub, ona görə də kod compile olunmur, bu səbəbdən A və F doğru fikirlər deyil. Bildiyimiz kimi Java çoxvarisliliyi dəstəkləmir, amma 11-ci sətirdə Grandchild
classı Grandma
və Grandpa
classlarının ikisini də eyni anda varis almaq istəyir. Bu səbəbdən compiler xəta verir.
6-cı sətirdə də xəta baş verir, çünki getAge()
metodunun gövdəsi yoxdur. Abstract class daxilində gövdəsiz metod elan edilərkən mütləq metodun adının əvvəlinə abstract
açar sözü əlavə edilməlidir. Grandpa
abstract class deyil, interface olsa idi, o zaman bu metod compile olunardı, çünki interface`də abstract
açar sözünün yazılması məcburi deyil.
Kodda daha bir compile xətası var. Maraqlıdır ki, 12-ci sətir də compile xətası var. Əslində compile xətası verməsi normaldır, metodların override edilməsi qaydalarında da qeyd etmişdik ki, child classdakı metodun access modifier`i parent classdakı metodla ən azı eyni olmalıdır, ya da ki, daha yüksək. Ona görə də 12-ci sətirdə getAge()
metodunun access modifier`i mütləq public
olmalıdır. Sadəcə 11-ci sətirdə çoxvarislilikdən dolayı xəta baş verdiyi üçün fikirləşmək olardı ki, Grandchild
Grandma
və Grandpa
classlarını düzgün varis almadığı üçün ola bilsin getAge()
metodunu override kimi görməsin. Amma sual qeyd edilən mənbədə (Sybex, Practise exam) də vurğulanıb ki, java compiler belə fikirləşmir, bunu da xəta kimi görür. Düzgün cavab – C, D, E
[topics lang=az]