• Web sitemizin içeriğine ve tüm hizmetlerimize erişim sağlamak için Web sitemize kayıt olmalı ya da giriş yapmalısınız. Web sitemize üye olmak tamamen ücretsizdir.
  • Sohbetokey.com ile canlı okey oynamaya ne dersin? Hem sohbet et, hem mobil okey oyna!
  • Soru mu? Sorun mu? ''Bir Sorum Var?'' sistemimiz aktiftir. Paylaşın beraber çözüm üretelim.

Polimorfizm

Üyelik Tarihi
7 Ocak 2015
Konular
4,091
Mesajlar
4,274
MFC Puanı
40
Polimorfizm eski yunanca bir kelime olup “birçok şekil” anlamına gelir. Polimorfizm OOP (objeye yönelik programlamada) ki en önemli kavramlardan biridir . Bu kavrami kullanarak daha gelişmiş kod organizasyonu , okunabilirlik ve genişleyebilir , programlar yazmanız daha kolaylaşır .Encapsulation , olaylarin esas döndüğü yer ile (veri tabani bağlantiları , algoritmalar..gibi) , kullanıcının gördüğü kısımları (methodları) private , frendly , protected gibi erişim belirliyicilerle birbirlerinden ayıran bir kavramdı . Geçen bölümden hatırlayacağınız kalıtım (inherentence) kavramında ,türemiş olan tiplerin nasil hem kendi tiplerinde veya ana tipde (türetildikleri tipde) ifade edildiklerini gördük. Polimorfizm ın diğer bir adı da “geç bağlama “, “run-time da bağlama” , veya “dinamik bağlamadır “ . Upcasting (Yukari doğru değişim)


Bu örnekte , üstünde durmamız gereken 3 adet class var , birinci ana class olan
Araba.class , ikincisi türemiş bir class olan AileArabasi.class , en sonuncusu ise yine türemiş bir class olan YarisArabasi class'ı. Buradaki ince nokta , AileArabasi objesini ben hem AileArabasi tipinde belirtebilirim hemde Araba tipinde belirtebilirim. Ama Araba tipinde belirtirsem, AileArabasi tipindeki obje kendisine ait özellikleri kaybeder. Yukarı doğru değişim herzaman class'ın özelliklerini daraltır. Aşagıdaki şemayı inceleyelim :



Bu şemayı koda dökelim :


// upcase ornek

class Araba
{
public **** sur() {
System.out.println("Araba Sur");
}
}

class YarisArabasi extends Araba
{
public **** sur() {
System.out.println("YarisArabasi Sur");
}

public **** hizYap() {
System.out.println("Hizzzz Yapp");
}
}

class AileArabasi extends Araba
{
public **** sur() {
System.out.println("AileArabasi Sur");
}
}

public class DenemeSurusu
{
public static **** arabaDene(Araba ar) {
ar.sur();
}

public static **** main(String args[]) {
arabaDene( new YarisArabasi() ) ;
}
}


arabaDene(Araba ar) , Araba tipinde bir obje kabul etmektedir ama biz bu metoda YarisArabasi tipinde bir obje gonderdiğimizde herhangi bir sorun çıkmadı . Bunun sebebi upcasting dir . Upcasting herzaman güvenlidir çünki daha fazla özellikli olan bir objeden daha genel tipdeki bir objeye geciş söz konusudur . Sonucda türemiş olan obje her zaman ana objenin methodlarına veya değişkenlerine sahip olacaktır(private lar hariç ) ama yeni türetilmiş olan bu objenin ekstradan methodları veya değişkenleri olabilir.
Downcasting , daha genel bir tipden daha gelişmiş bir değişim ise upcasting kadar basit ve güvenli olmayabilir .Eğer bir yer de upcasting veya downcasting den bahsediliyorlar orada kesinlikle inheritance (kalıtım) vardır .

Program çıktısı aşağıdaki gibi olur :
YarisArabasi Sur

Zor Yol


Hemen örneğimize geçelim

// overload
class Araba
{

private int i = 0 ;
public **** sur() {
System.out.println("Araba Sur");
}

}

class YarisArabasi extends Araba
{
public **** sur() {
System.out.println("YarisArabasi Sur");
}

public **** hizYap() {
System.out.println("Hizzzz Yapp");
}
}

class AileArabasi extends Araba {
public **** sur() {
System.out.println("AileArabasi Sur");
}
}


class YukArabasi extends Araba {

public **** sur() {
System.out.println("YukArabasi Sur");
}
}

public class DenemeSurusu2 {


public **** arabaGit(YarisArabasi ar) {
ar.sur();
}

public **** arabaGit (AileArabasi ar ) {
ar.sur() ;
}

public **** arabaGit( YukArabasi ar ) {
ar.sur() ;
}

public static **** main(String args[]) {
DenemeSurusu2 ds2 = new DenemeSurusu2();
YarisArabasi ya = new YarisArabasi();
AileArabasi aa = new AileArabasi();
YukArabasi yua = new YukArabasi();
ds2.arabaGit( ya );
ds2.arabaGit( aa );
ds2.arabaGit( yua );
}
}


Program gayet basit ve temiz . Her objenin sur() methodunu çağırabilmek için ayrı ayrı methodlar yazdık ve bunlar overload etti . (overload : aynı ismi birçok metod için kullanabilme , argumenetleri KESINLIKLE farklı olmak koşulu ile).
Biz ne zaman yeni bir tip araba üretsek(türetsek) bunun için hemen gelip program içinde yeni bir method yazamamız gerekli ki ilgili objenin sur() methodu çağrılabilsin. Zor iş !! . Peki şöyle tek bir method olsa da biz programa yeni bir araba tipi ilave ettiğimizde , bu yeni üretilen(türetilen) arabanın sur() metodu otomatik olarak çağrılsa , her şey tek metod da bitse ne hoş olurdu .Hayali bile güzel.

Polimorfizim size bu yapmanızı sağlar. İlk bakışda biraz anlamsız veya sihir gibi gelebilir ama hayatı kolaylaştıran bir kavram olduğu kesin.

Tek Soru Değişik Cevaplar


Polimorfizm i kısaca cok genel olarak şöyle tanımlayabiliriz . Tek soru değişik cevaplar .

Öncelikle aşağıdaki şemayı inceleyelim :



At , Kuş ve Kurbağa , Hayvan sınıfından türemiş olsunlar ve konus() metoduda her objede ezilsin (override edilsin , birazdan anlatılacak).



Biz buradaki üç adet değişik objeye aynı soruyu soruyoruz : konus() , ama objelerin bana geri dondukleri cevaplar birbirlerinden farklı .

Yukarıdaki şemaları koda dökelim :

// polimorfizm ornegi
class Hayvan
{
public **** konus() {
System.out.println("Hayvan Konus()");
}
}

class At extends Hayvan
{
public **** konus() {
System.out.println("At Konus() --> Aii Aii");
}
}

class Kus extends Hayvan
{
public **** konus() {
System.out.println("Kus Konus() --> Cik Cik ");
}
}

class Kurbaga extends Hayvan
{
public **** konus() {
System.out.println("Kurbaga Konus() --> virakkk ");
}
}

public class Doga
{

public static Hayvan rastgeleObjeDondur() {
switch((int)(Math.random() * 3)) {
default:
case 0: return new At();
case 1: return new Kus();
case 2: return new Kurbaga();
}
}

public static **** main(String[] args)
{
Hayvan[] s = new Hayvan[10];
// Array icini rastgele At , Kus veya Kurbaga objeleri ile dolduracagiz
for(int i = 0; i < s.length; i++) {
s = rastgeleObjeDondur(); // upcasting oluyor dikkat !!
}

for(int i = 0; i < s.length; i++) {
s.konus() ; //hangi objenin metodu cagirilacak
} // su an da bilemeyiz , rastgele.. run-time da belli olacak

}
}



Hayvan class ı diğer kendinden türemiş veya türeyecek olan classlar için bir temel oluşturmakda - yani Hayvan class ından türeyen her yaratık konusma özelliğine sahip oluyor daha sonra bu konus() methodunu ezerek (override) , kendisine has bir üsluba sahip oluyor.

Doğa class ında bulunan ve static bir method olan rastgeleObjeDondur() , rasgele At,Kus veya Kurbaga objeleri geri döndürüyor . Bu döndürülen rastgele objeler Hayvan tipinde tanımlanmış bir Array ın içine atılıyorlar .Bu Array içine atılma anında bir upcating(yukarı dogru değişim) söz konusu , daha özellikli bir tipden daha genel bir tipe doğru değişim (%100 güvenli , risk yok ) . Daha sonra Array içine atılan objeleri çekip çıkarıyoruz ve bu objelerin konus() methodu cağırıyoruz .

Programın çıktısı :

Kus Konus() --> Cik Cik
Kus Konus() --> Cik Cik
At Konus() --> Aii Aii
Kurbaga Konus() --> virakkk
At Konus() --> Aii Aii
Kurbaga Konus() --> virakkk
Kus Konus() --> Cik Cik
Kus Konus() --> Cik Cik
Kus Konus() --> Cik Cik
Kurbaga Konus() --> virakkk


Program her seferinde değişik sonuclar üretmeye devam edecektir.
Bizim yazdığımız tek bir satır kod ile
s.konus() ;

Hayvan sinifindan ne kadar yaratık türetirsek türetelim , bu türetilen yeni yaratıkların konus() methodlarını çağırmak için ekstra bir kod yazmamız gerekmeyecektir, konus(
 
Üst