Overriding and Overloading

Merhaba arkadaşlar, bu yazımızda Overriding ve Overloading konularına değinmeye çalışacağım. Bu iki konuyu iyi kavramak faydalı olucaktır.

Overriding

Temel olarak bir methodun alt sınıflarca yeniden tanımlanması/declare edilmesi/ezilmesi anlamına gelmektedir. Bir diğer deyişle alt sınıfların spesifik olarak kendi sınıfı için davranmasını sağlamak demektir. Override edilmek istenen methodların final olmaması gerekir. Bir sınıfı extends eden sınıf , süper class’ın özelliklerine de sahip oldugunu biliyoruz. Bir örnek üzerinden bakalım;

a.eat(); methodunun çıktısı beklenen şekilde “Animal eating” olmuştur. Override edilen eat methodu Horse objesi için subtype class içinde spesifik şekilde Horse classına göre düzenlenmiştir. Eat methodunu override eden Horse classının instance’ı eat() methodunu çağırdığında “Horse eating” çıktısı oluşacaktır. Burada dikkat etmemiz gereken nokta ise Animal ah = new Horse(); satırı olucaktır. Yukarıdaki ah nesnesi Animal referansa sahip ama Horse objesidir. ah objesi eat methodunu çağırdığında “Animal eating” yerine “Horse eating” çıktısı alınacaktır. Override edilen methodlarda referans değişkeni yerine objenin türüne bakılır!

Animal class burada poliformizmi uygulatan sınıf konumundadır. Her animal(hayvan) yemek yer, Animal class der ki; her hayvan yemek yer ama At( at’da hayvan ) olan hayvan başka türlü yer Köpek olan hayvan başka türlü yer. Bu nedenle benim alt sınıflarım bu işlevi kendi ihtiyaçları ve gereksinimlerine göre düzenlesinler.

Abstract methodların alt sınıflarca impelemete edilmesi zorunludur. Ancak sub class abstract class ise methodu impelemente edilmek zorunda değildir, opsiyoneldir. Somut olan(concrete class/abstract olmayan) ilk alt sınıfta abstract methodun implemente edilmesi kuralı vardır.

Şimdi Horse sınıfına yeni bir method ekleyelim ve Animal referanslı Horse objesi ile bu methodu çağırmaya çalışalım;

Methodu çağıralım;

Compile error oluşacaktır.  Animal class’ı buck() adlı bir methoda sahip değildir. Bu yüzden Animal referanslı bir obje buck methodunu çağıramayacaktır. Şunu unutmayalım; Animal referans değişkeni üzerinden bir method çağrımı yapıldığında compiler yanlızca Animal sınıfı içerisinde bulunan methodlara izin verecektir. Compiler burada reference type’a bakar instance type’a değil.

Not 0 : Overriding olan methodlar alt sınıflarca daha fazla kısıt getirecek şekilde access modifiers’a sahip olamazlar. Örnek olarak public olan bir method alt sınıfta protected/private olarak override edilemezler. Animal reference ve Horse objesine sahip obje üzerinden eat methodu çağrıldığında eat methodonun çıktısı runtime anında belli olacaktır. Burada C++ da bulunan virtaul methodların Java’da olmaması nedeni vardır. Aslında Java’da virtaul method vardır zaten kullanıyoruz ama bilmiyoruz . Java, runtime anında mevcut nesne üzerinden virtaul methodu çağrımını yapacaktır.

Not 1 : Override edilen methodlarda bir takım kurallara uymak mecburiyeti vardır. Şurada 23 January 2015 tarihli Tips&Trick yazımda buna değinmiştim, lütfen oraya da bakınız.

Not 2 : Override edilen method içerisinde üst sınıftaki methoda çağrım yapılabilir. Horse class’ı içerisinde ki eat methodunda super.eat(); çağrımını yapabilirsiniz.

Note 3 : Yeri değil ama bilmekte fayda var. super çağrısını instance methodlarda yapabilirsiniz. Static olan methodlarda super deyimi ile üst sınıftaki methoda çağrım yapamazsınız.

Overloading

Aynı class içerisinde aynı isimli method declarasyonunun yapılmasına overloading denir. Bir methodun overloading edilmesi için farklı argüman tiplerine sahip olması gerekmektedir. Return type da farklı olabililir ama opsiyoneldir. Return type farklı olması için IS-A ilişkisine sahip olunmalıdır. Örn; Animal return eden bir method overloading edilmek istenirse return type olarak Animal da verilebilir Horse da verilebilir. Horse, IS-A Animal(At, bir hayvandır).

  • Overloaded edilen methodda argüman listesi farklı olmak zorundadır.
  • Overloaded edilen methodda return type değiştirilebilir.
  • Overloaded edilen methodda accees modifiers değiştirilebilir.
  • Overloaded edilen methodda yeni exception declarasyonu yapılabilinir.
  • Aralarında IS-A ilişkisi bulunan sınıflarda aynı isimli ve farklı argüman listesine sahip method declarasyonu yapıldığında yapılan işem Overriding değil Overloaded işlemidir. Örn; Horse class içerisindeki eat methoduna bir argüman eklediğinizde eat methodu overriding değil overloaded olunmuş olucaktır.

Legal Overloaded;

Compiler hangi overloaded methodunun çağrıldığına karar vermek için methodlara gönderilen parametrelere bakmaktadır.

Overloaded edilen methodlarda parametre olarak primitive yerine Object yazarsak farklı şeyler olabiliyor

Bir örnek ile devam edelim;

Çıktı;

Gelen obje tipine göre ilgili method çağrılacaktır. Birde şunu deneyelim;

Animal reference ile Horse objesi olan animlRefToHorse doStuff methodunu çağırdığında hangi method çağrılacaktır?

Horse ojbesi olduğu için Horse objeyi parametre olarak alan  methodun çağrılacağını düşünürsünüz ama öyle olmayacaktır. Çıktımız şu olucaktır; in the Animal version.

Nedenine gelicek olursak; Yukarıdaki method runtime anında Horse objesidir. Overloaded edilen method çağrımı yapıldığında ise object type değil reference type’a bakılır. Animal reference’a sahip olunduğu için animal objeyi parametre alan method çağrılacaktır.

Not 0 : Override edilen methodların hangisinin çağrılacağı runtime anında bellidir ve object type’a bakılır bunun için. Overloaded edilen methodlarda ise compile anında gönderilen parametrelere ve reference type’a bakılır. Override, runtime(dynamic) polymorphizm ve Overloaded, compile time(static) polymorphizm olarak adlandırılır.

 

Bunu iyice kavramak için şu örneği yapalım;

Horse sınıfımızda eat methodunu hem overloaded hem overriding edilmiş versiyonları mevcut. Şimdi de kullanalım;

Animal a = new Animal(); a.eat(); ile çağrıldığında Generic Animal Eating Generically çıktısı verilecektir.

Horse h = new Horse(); h.eat(); ile çağrıldığında Horse eating hay çıktısı verilecektir.

Animal ah = new Horse(); ah.eat(); ile çağrıldığında Horse eating hay çıktısı verilecektir. Burada polymorphizm gerçekleşmiştir. Object type hangi methodun çağrılacağına karar verir reference type değil.

Horse he = new Horse(); he.eat(“Apples”); ile çağrıldığında Horse eating apples çıktısı verilecektir. Overloaded olan eat methodu çağrılacaktır.

Animal a2 = new Animal(); a2.eat(“treats”); ile çağrıldığında compiler error oluçaşaktır. Animal reference ile overloaded edilen method çağrılmak istenmiştir. Animal class içerisinde böyle bir method mevcut değildir.

Animal ah2 = new Horse(); ah2.eat(“Carrots”); ile çağrıldığında yine compile error oluşur. Horse objesi olmasına rağmen yine reference type’a bakılır , Animal class’da böyle bir method olmadığı için hata oluşur.

Bu konulara dikkat edelim arkadaslar , temel konular olması ile birlikte buraları yanlış bilirseniz ilerde çok sıkıntı yaşayabilirsiniz. Bol pratik yapıp kod yazmayı deneyin. Aynısını yazın hiç farketmez ama sadece okumakla kalmayın.

Yazımı burada sonlandırmak istiyorum arkadaşlar.

Mutlu kalın, kod’la kalın ve bol bol Çay için

~ Alican Akkus

 

910 Total Views 1 Views Today