OCA Java imtahan mövzuları

Overloading Methods

Eyni ada, lakin müxtəlif parametr listinə (different method signature) sahib olan metodlar overload metodlar adlanır. Signature`nin tərkibinə daxildir:

  1. metod adı;
  2. parametr siyahısı.

Overload metodlarda metod adından başqa hər şey fərqli ola bilər (məsələn: access modifiers, specifiers (like static), return types və exception lists).

Overload metodlar əsasən parametr listinə görə təyin olunur, yəni bu metodlar üçün vacib qayda budur ki, ad eyni olsun, parametr listi fərqli. Fərqli dedikdə nə nəzərdə tutulur:

  • parametrlərin sayı müxtəlif olmalıdır;
  • parametrlərin sayı eyni ola bilər, o halda ki:
    • tipləri fərqli olmalıdır;
    • ardıcılıq fərqli olmalıdır.

Nümunə:

public void fly(int i) {}
public void fly(short s) {}
public boolean fly() { return false; }
void fly(int i, short s) {}
public void fly(short s, int i) throws Exception {}
  
int fly(int i, short s){ return 0; }            // doesn’t compile, for line 8
public static final void fly(short a, int b){}  // doesn’t compile, for line 9

 

 

Overloading and Varargs

Java varargs`la massiv kimi davranır. Əgər biz parametr olaraq int[] göndərsək, hansı metod çalışacaq?

public void fly(int[] array) {}
public void fly(int... varargs) {}    // DOES NOT COMPILE

2-ci metod compile olunmayacaq, çünki java bunların hər ikisi üçün metod signature`ni eyni cür görür. Əgər ayrı-ayrılıqda compile olunsa, parametr olaraq massiv göndərilsə hər iki metod çalışacaq. Yalnız varargs`ın çalışmasını istəyiriksə, massiv elementlərini tək-tək göndəririk:

fly(new int[] {1, 2, 3} );    // both of them
fly(1, 2, 3);                 // only varargs

 

 

Autoboxing
public void fly(int i){}       
public void fly(Integer i){}

Əgər bizim intInteger parametr qəbul edən metodumuz varsa, onu fly(5); olaraq çağırsaq 1-ci metod işləyəcək, 1-ci metod olmasa, o zaman 2-ci metod çağırılacaq. Çünki java həmişə ilk olaraq dəqiq uyğunluq olan parametri tapmağa çalışır. Əgər int parametrli metod mövcuddursa, heç bir səbəb yoxdur ki, java int`i İnteger`ə autoboxing edərək əlavə iş görsün. Əgər Integer i = 5; elan edib i dəyişənini fly metoduna göndərsək o zaman 2-ci metod işləyəcək.

 

 

Primitive and Reference Types

Qeyd etdiyimiz kimi birinci dəqiq uyğunluq tapılır, sonra digər etaplar nəzərdən keçirilir. Aşağıdakı kod nümunəsində əgər bizim int parametr qəbul edən metodumuz olmasa, long parametrli metod çağırılır, çünki daha geniş tipə malik parametrli metodu çağırmaq java üçün problem deyil, amma əksi mümkün deyil, çünki java daha kiçik tipə avtomatik çevirmə etmir.

class OverloadingTest {
    public void fly(int i) {
        System.out.print("int ");
    }
    public void fly(long l) {
        System.out.print("long ");
    }
    public void fly(Object o) {
        System.out.print("object ");
    }
    public static void main(String[] args) {
        OverloadingTest obj = new OverloadingTest();
        obj.fly(123);
        obj.fly(123L);
        obj.fly((short) 123);
        obj.fly(123.0);
    }
}

Output:

int long int object

 

Main metodda sonuncu sətirdə double tipli parametr göndəririk. İlk öncə double tipi axtarılır, dəqiq uyğunluq tapılmadığına görə double autoboxing olaraq Double tipinə çevirilir. Və yenə dəqiq uyğunluq tapılmadığına görə Object parametrli metod çağırılır.

 

 

Putting It All Together

Overload metodların işləmə ardıcıllığı aşağıda cədvəldə göstərilib*:

class TestOverloading {
    public static void main(String[] args) {
        System.out.print(glide());
        System.out.print(glide("a"));
        System.out.print(glide("a", "b"));
        System.out.print(glide("a", "b", "c"));
    }
    public static String glide(String s) {
        return "1";
    }
    public static String glide(String... s) {
        return "2";
    }
    public static String glide(Object o) {
        return "3";
    }
    public static String glide(String s, String t) {
        return "4";
    }
}

Output: 

2142

 

Varargs parametrli metoda boş parametr də göndərə bilərik, bu zaman java boş massiv göndərir.

Java ən dəqiq uyğunluq olan parametri axtaran zaman ancaq bir çevirmə (one conversion) edir.

public class TooManyConversions {
    // public static void play(Object o) {}   
    public static void play(Long l) {}
    public static void play(Long... l) {}
    public static void main(String[] args) {
        play(4);     // DOES NOT COMPILE
        play(4L);    // calls the Long version
    }
}

Yuxarıdakı nümunədə problem çevirmə ilə bağlıdır. Java int 4`ü long 4 və ya Integer 4`ə rahatlıqla çevirir. Amma bir addıma int`i Long`a çevirə bilmir, gərək əvvəlcə int`i long`a çevirsin, sonra da long`u Long`a, yəni iki addıma. İki çevirmə də mümkün deyil. Amma əgər 1-ci metodu commentdən çıxarsaq, kod compile olunacaq. Çünki bu zaman ancaq bir çevrilmə yerinə yetiriləcək: int`dən Integer`ə. Integer də obyekt olduğundan birinci metod çağırılacaq.

int parametr qəbul edən metod həm char, həm də int tipini çağıra bilir. Amma char tipində parametr qəbul edən metod int tipini çağıra bilmir. Aşağıdakı nümunəyə Enthuware testlərində rast gələ bilərsiniz:

class Noobs {
     public void m(int a) { System.out.println("In int "); }     // line1
     public void m(char c) { System.out.println("In char "); }   // line2
     public static void main(String[] args) {
        Noobs n = new Noobs();
        int a = 'a';
        char c = 6;
        n.m(a);      // line3
        n.m(c);      // line4
    }
}

Əgər line2 commentə alınsa kod normal işləyəcək, amma line1 commentə alınsa line3 compile xətası verəcək.

Enthuware sual bankından daha bir maraqlı nümunə ilə tanış olaq və səbəbini öyrənək:

class TestClass {
   public void method(Object o){
      System.out.println("Object Version");
   }
   public void method(java.io.FileNotFoundException s){
      System.out.println("java.io.FileNotFoundException Version");
   }
   public void method(java.io.IOException s){
      System.out.println("IOException Version");
   }
   public static void main(String args[]){
      TestClass tc = new TestClass();
      tc.method(null);
   }
}

Sualdan da aydın göründüyü kimi hər üç metod null parametrini qəbul edir, bəs maraqlıdır ki, kodu run etsək hansı metod çalışacaq? Əvvəlki yazılarımızda da qeyd etdik ki, Java birinci ən dəqiq uyğunluğu (the most specific) axtarır. Bildiyimiz kimi FileNotFoundException classı IOException classının subclass`ıdır, ona görə də bu nümunədə “the most specific class” FileNotFoundException classı hesab edilir.

Əgər “most specific class” sayı bir deyil iki olarsa, onda nə baş verəcək? Yuxarıdakı kod nümunəsini biraz fərqli şəkildə yazaq və nəticəyə baxaq:

public class TestClass {
   public void method(Object o){
      System.out.println("Object Version");
   }
   public void method(String s){
      System.out.println("String Version");
   }
   public void method(StringBuilder s){
      System.out.println("StringBuilder Version");
   }
   public static void main(String args[]){
      TestClass tc = new TestClass();
      tc.method(null);    // DOES NOT COMPILE
   }
}

Aşağıdakı compile xətası ilə qarşılaşacağıq:

reference to method is ambiguous
both method method(String) in TestClass and method method(StringBuilder) in TestClass match

Məhz bu səbəbdən kod sətrinə System.out.println(null); yazdıqda compile xətası verir, çünki println() overload metoddur və parametr olaraq null göndərdikdə birdən çox uyğunluq tapılır.

Mövzunu tam dərk etdiyinizə əmin olmaq üçün sonda Enthuware-dən daha bir kod nümunəsi qeyd edəcəm, çox maraqlı sualdır. Kod nümunəsini dəyişərək ağlınıza gələn bir neçə kombinasiyada yoxlaya bilərsiniz. Belə olduqda sizə qaranlıq qalan məqamları özünüz üçün aydınlatmış olacaqsınız. Suallarınız yaranarsa, commentdə qeyd edə bilərsiniz.

class TestClass {
    
    void probe(int... x) { System.out.println("In ..."); }  
    
    void probe(Integer x) { System.out.println("In Integer"); } 
    
    void probe(long x) { System.out.println("In long"); } 
    
    void probe(Long x) { System.out.println("In LONG"); } 
    
    public static void main(String[] args){
        Integer a = 4; new TestClass().probe(a); 
        int b = 4; new TestClass().probe(b); 
    }
}

 

[topics lang=az]

 

“OCA: Oracle Certified Associate Java SE 8 Programmer I Study Guide: Exam 1Z0-808”, by J.Boyarsky & S.Selikoff

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.