Java da Nesne Yönelimli Tasarım Kavramları
Merhaba arkadaşlar bu yazımızda java üzerinde nesne yönelimli tasarım kavramlarından bahsedip, bu kavramları içeren bir örnek uygulama yapacağız.
Kısaca terimlerden bahsetmek gerekirse,
Inheritence: Yani kalıtım, nesne yönelimli programlamanın temelidir denebilir. Bir class’ın içerisinde barındırdığı özelliklerini, kendisini kalıtım yoluyla extend eden class’a aktarmasıdır.
Abstract Method: Bir class ta bulunan abstract olarak belirtilmiş methodun içeriğinin, bu class’ı extend eden class tarafından implement edilecek olmasıdır.
Abstract Class: Bu class’ı kullanabilmek için mutlaka başka bir class tarafından extend edilmesi gerekmektedir.
Composition: Bir class’ın başka bir class içerisinde attribute olarak bulunmasıdır.
Polymorphism: Çok biçimlilik anlamına gelmektedir. Bir metodun override edilmesi veya overload edilmesi ile oluşan yapılara denir.
Inteface: Kendisini extend edecek class’a hangi metodları implement edeceğini belirten ve bu yolda zorlayan yapıdır.
Şimi bu kavramları örnek üzerinde inceleyelim. Yapacağımız uygulama sipariş sistemi olacak.
Kullanacağımız ana class’larımız: Müsteri, Masa, Menu dur. Ayrıca, OdemeSistemi adında Interface, Icecek ve Yiyecek adında alt class’lar bulunmaktadır.
Öncelikle Müsteri class’ımız OdemeSıstemi Interface’ini implement edecek ve bu sayede OdemeSistemi’nde bulunan metodlar zoraki olarak Musteri içerisinde implement edilecek. Masa class’ımızın içinde Musteri attribute’u bulunacak. Ayrıca Menu class’ından Icecek ve Yiyecek class’ları extend edilecek.
Kısaca yapılardan bahsedip uygulamayı paylaşalım.
Musteri class’ı OdemeSistemi interface’ini implement etmektedir. Masa class’ının içinde Musteri class’ı bulunması bir composition dur. Menu class’ından Icecek ve Yiyecek extend edilmesi inheritence’e örnektir. Ayırca Menu class’ı abstract’tır.
Kodları burada paylaşıyorum, ayrıca sayfanın altındaki linkten indirebilirsiniz.
OdemeSistemi:
/** * Ödeme sistemine ihtiyaç duyan tüm classlar bu interface'i implement * edeceklerdir. Böylece ödeme sistemi yazılırken eksik kalan bir nokta * olmayacaktır. * * @author Gürcan Kavakçı * */ public interface IOdemeSistemi { // -1 hala borcu var, 0 borcu yok, 1 alacaklı /** * Toplam borç üzerinden ödeme yapılmasını sağlar * @param miktar * @param odemeSekli * @return basarıDurumu */ public int odemeYap(double miktar, String odemeSekli); /** * Implement eden class'ın borcunu döndürür. * @return borc */ public double borcSorgula(); /** * Implement eden class'a yeni bir borç ekler. * @param borc */ public void borcEkle(double borc); } |
Musteri:
import java.util.ArrayList; /** * Sipariş sistemini kullanan yapıların müşteri kısmını tutar. Ödemeler müşteri * üzerinden olacağı için OdemeSistemi interface'ini implement eder. * * @author Gürcan Kavakçı * */ public class Musteri implements IOdemeSistemi { // Kişisel bilgiler private String isim; private boolean iskayitliMusteri; private int kartNo; // borç ve bakiye bilgileri private double borc; private double odenen; private double bakiye; // Geçmişe dönük kayıt için private ArrayList<String> odemeSekli; private ArrayList<String> odenenMiktar; /** * Normal müşteri yaratılır. * @param isim */ public Musteri(String isim) { this.isim = isim; odemeSekli = new ArrayList<>(); odenenMiktar = new ArrayList<>(); } /** * Sisteme kayıtlı müşteri yaratılır * @param isim * @param kartNo */ public Musteri(String isim, int kartNo) { this.isim = isim; this.iskayitliMusteri = true; this.kartNo = kartNo; odemeSekli = new ArrayList<>(); odenenMiktar = new ArrayList<>(); } @Override public int odemeYap(double miktar, String odemeSekli) { // bakiyesini yatırdığı paraya ekliyoruz. miktar += bakiye; bakiye = 0; // borcu var if (borcSorgula() > 0) { // yatırdığı para fazla if (miktar > borcSorgula()) { bakiye = miktar - borcSorgula(); this.odenenMiktar.add(Double.toString(borcSorgula())); this.odemeSekli.add(odemeSekli); odenen = borc; return 1; } // tam para yatırmış else if (miktar == borcSorgula()) { this.odenenMiktar.add(Double.toString(borcSorgula())); this.odemeSekli.add(odemeSekli); odenen = borc; return 0; } // eksik para yatırmış else { this.odenenMiktar.add(Double.toString(miktar)); this.odemeSekli.add(odemeSekli); odenen += miktar; return -1; } } // borcu yok else { bakiye = miktar; return 1; } } @Override public double borcSorgula() { return borc - odenen; } @Override public void borcEkle(double borc) { this.borc += borc; } public String getIsim() { return isim; } public void setIsim(String isim) { this.isim = isim; } public boolean isIskayitliMusteri() { return iskayitliMusteri; } public void setIskayitliMusteri(boolean iskayitliMusteri) { this.iskayitliMusteri = iskayitliMusteri; } public int getKartNo() { return kartNo; } public void setKartNo(int kartNo) { this.kartNo = kartNo; } public double getBorc() { return borc; } public void setBorc(double borc) { this.borc = borc; } public double getOdenen() { return odenen; } public void setOdenen(double odenen) { this.odenen = odenen; } public double getBakiye() { return bakiye; } public void setBakiye(double bakiye) { this.bakiye = bakiye; } public ArrayList<String> getOdemeSekli() { return odemeSekli; } public void setOdemeSekli(ArrayList<String> odemeSekli) { this.odemeSekli = odemeSekli; } public ArrayList<String> getOdenenMiktar() { return odenenMiktar; } public void setOdenenMiktar(ArrayList<String> odenenMiktar) { this.odenenMiktar = odenenMiktar; } } |
Masa:
import java.util.ArrayList; /** * Masa class'ı işletmede siparişlerin ve müşterilerin buluştuğu class'tır. * Sipariş verilen menülere, borçlara vs Masa class'u üzerinde erişilir. * * @author Gürcan Kavakçı * */ public class Masa { private Musteri musteri; private ArrayList<Menu> menuler; private String masaAdi; private int kapasite; /** * Müşterisi yeni olan masalardır. * @param adi * @param kapasite */ Masa(String adi, int kapasite) { this.masaAdi = adi; this.kapasite = kapasite; this.musteri = new Musteri(""); menuler = new ArrayList<>(); } /** * Daha önceden rezervasyonu yapılmış, müşterisi belli olan masalardır. * @param adi * @param kapasite * @param musteri */ Masa(String adi, int kapasite, Musteri musteri) { this.masaAdi = adi; this.kapasite = kapasite; this.musteri = musteri; menuler = new ArrayList<>(); } /** * Sipariş verilen menüleri masalara atar. * @param menu */ public void siparisVer(Menu menu) { menuler.add(menu); musteri.borcEkle(menu.fiyatHesapla()); System.out.println(masaAdi + ", " + menu.getIsmi() + " sipariş verdi."); } /** * Siparişlerin toplu bir şekilde verilmesini sağlayan method * @param menuler */ public void siparisVer(ArrayList<Menu> menuler) { String siparisler = " "; for (Menu menu2 : menuler) { this.menuler.add(menu2); siparisler += menu2.getIsmi() + ", "; musteri.borcEkle(menu2.fiyatHesapla()); } System.out.println(masaAdi + ", " + siparisler + " sipariş verdi."); } /** * Verilen siparişlerden sonra ne kadar bekleneceğini hesaplayan method * @return sure */ public int beklenecekSure() { int sure = 0; for (Menu menu : menuler) { if (menu instanceof Yiyecek) { if (sure < ((Yiyecek) menu).getSure()) { sure = ((Yiyecek) menu).getSure(); } } } return sure; } /** * Bekleme süresini ekrana basar. */ public void beklenecekSureGoster() { System.out.println(getMasaAdi() + " in bekleme süresi: " + beklenecekSure() + " dk."); } /** * Borcu ekrana basar */ public void toplamBorcGoster() { System.out.println(getMasaAdi() + " in toplam borcu: " + musteri.borcSorgula()); } /** * Müşterisi belli olmayan masaya müşteri atamak için kullanılan metod * @param musteri */ public void MusteriEkle(Musteri musteri) { this.musteri = musteri; } public Musteri getMusteri() { return musteri; } public void setMusteri(Musteri musteri) { this.musteri = musteri; } public ArrayList<Menu> getMenuler() { return menuler; } public void setMenuler(ArrayList<Menu> menuler) { this.menuler = menuler; } public String getMasaAdi() { return masaAdi; } public void setMasaAdi(String masaAdi) { this.masaAdi = masaAdi; } public int getKapasite() { return kapasite; } public void setKapasite(int kapasite) { this.kapasite = kapasite; } } |
Menu:
/** * Sipariş sistemi ile çalışan bir işletmenin menü yapısını tutar. Menu abstract * bir class olup, yiyecek ve içeceklerde ortak bulunan isim fiyat gibi * bilgileri tutar. * * @author Gürcan Kavakçı * */ public abstract class Menu { protected String ismi; protected double fiyat; Menu() { ismi = ""; fiyat = 0.0; } /** * İsim ve fiyat ile yeni menü yaratılır * * @param ismi * @param birimFiyat */ Menu(String ismi, double birimFiyat) { this.ismi = ismi; this.fiyat = birimFiyat; } /** * Abstract method olan fiyatHesapla, kendini extend eden class tarafından * doldurulacaktır. * * @return fiyat */ public abstract double fiyatHesapla(); public String getIsmi() { return ismi; } public void setIsmi(String ismi) { this.ismi = ismi; } public double getFiyat() { return fiyat; } public void setFiyat(double fiyat) { this.fiyat = fiyat; } } |
Icecek:
/** * Sipariş sistemini kullanan işletmelerin içeceklerini tutabileceği yapıdır. * Menu abstract classını extend eder. Menu den farklı olarak içeceğin boyutunu * tutan field'a sahiptir. * * @author Gürcan Kavakçı * */ public class Icecek extends Menu { // içeceğin boy oranları private int boy; Icecek(String ismi, double birimFiyat, int boy) { super(ismi, birimFiyat); this.boy = boy; } @Override public double fiyatHesapla() { return boy * fiyat; } public int getBoy() { return boy; } public void setBoy(int boy) { this.boy = boy; } } |
Yiyecek:
/** * Sipariş sistemini kullanan işletmelerin yiyeceklerini tutabileceği yapıdır. * Menu abstract classını extend eder. Menu den farklı olarak yiyeceğin * hazırlanma süresini tutan field'a sahiptir. * * @author Gürcan Kavakçı * */ public class Yiyecek extends Menu { // yiyeceğin hazırlanma süresi private int sure; Yiyecek(String ismi, double birimFiyat, int sure) { super(ismi, birimFiyat); this.sure = sure; } @Override public double fiyatHesapla() { return fiyat; } public int getSure() { return sure; } public void setSure(int sure) { this.sure = sure; } } |
main:
import java.util.ArrayList; /** * Yazılan class ların test ortamı sağlanır. * * Hazırlanan uygulama şu şekilde çalışmaktadır. Öncelikle Müsteri class'ımız * bulunmakta ve müşteri ödeme yapacağı için OdemeSistemi interface'ini * implement etmektedir. Müşteriler için hazırlanmış yiyecekler için, abstract * bir Menu class'ı mevcuttur. Bu class'ta genel bilgiler tutulmaktadır. Bu * class'tan Icecek ve Yiyecek class ları türemiştir. Bunları birbirinden ayıran * özellikleri, iceceklerin boy oranları olması, yiyeceklerin ise hazırlanma * sürelerinin olmasıdır. İşlemler Masa class'ı üzerinden yürümektedir. Her masa * nın ödeme yapacağı bir müşterisi vardır. Ayrıca her masada seçilen yiyecek ve * içecekleri tutan Menu listesi vardır. İşlemler ve siparişler masalar * üzerinden yapılmaktadır. * * interface: IOdemeSistemi interface'i Musteri class'ı tarafından implement * edilmiştir. inheritence: Menu class'ı Icecek ve Yiyecek class ları tarafından * extend edilmiştir. abstract class ve method: Menu class'ı abstractır. * composition: Masa class'ı Musteri class'ına sahiptir. Masa class'ında yiyecek * ve içecekleri beraber tutabileceğimiz Menu tipinde liste vardır. * * Masa class'ında bulunan beklenecekSure() metodunda menu cinsinden bir * değişkenin getSure() metoduna erişilmeye çalışılmıştır. Ancak getSure() * sadece Yiyecek class'ında mevcuttur. Bu yüzden öncelikle menu değişkeninin * gerçekten Yiyecek classından mı yaratıldığını anlamak için "instanceof" * kontrolü kullanılmıştır. * * @author Gürcan Kavakçı * */ public class main { /** * Test * * @param args */ public static void main(String[] args) { // Menuler oluşturuluyor Yiyecek pide = new Yiyecek("Pide", 5, 15); Yiyecek lahmacun = new Yiyecek("Lahmacun", 3, 12); Yiyecek beyti = new Yiyecek("Beyti", 8, 20); Yiyecek kavurma = new Yiyecek("Saç Kavurma", 8, 20); // İçecekler oluşturuluyor Icecek ayran = new Icecek("Ayran", 0.5, 1); Icecek ayranBuyuk = new Icecek("Büyük Ayran", 0.5, 2); Icecek kola = new Icecek("Kola", 0.8, 1); Icecek kolaOrta = new Icecek("Orta Kola", 0.8, 2); Icecek kolaBuyuk = new Icecek("Büyük Kola", 0.8, 3); Icecek cay = new Icecek("Çay", 0, 1); // Masalar oluşturuluyor Masa masa1 = new Masa("Masa1", 4); Masa masa2 = new Masa("Masa2", 6); // Müşteriler Musteri musteri1 = new Musteri("Gürcan"); Musteri musteri2 = new Musteri("Onur"); Musteri musteri3 = new Musteri("Melike"); Musteri musteri4 = new Musteri("Burak"); // Masalara müşteri atanıyor masa1.MusteriEkle(musteri1); masa2.MusteriEkle(musteri2); // Müşterili masa yaratılıyor Masa masa3 = new Masa("Masa3", 5, musteri3); Masa masa4 = new Masa("Masa4", 4, musteri4); // Siparişler veriliyor /* tek sipariş */ masa1.siparisVer(pide); masa1.siparisVer(ayranBuyuk); masa1.beklenecekSureGoster(); /* toplu sipariş */ ArrayList<Menu> masa2Siparisler = new ArrayList<>(); masa2Siparisler.add(beyti); masa2Siparisler.add(lahmacun); masa2Siparisler.add(kolaOrta); masa2Siparisler.add(cay); masa2.siparisVer(masa2Siparisler); masa2.beklenecekSureGoster(); // Hesaplar ödeniyor masa1.toplamBorcGoster(); masa2.toplamBorcGoster(); masa1.getMusteri().odemeYap(masa1.getMusteri().borcSorgula(), "Nakit"); masa2.getMusteri().odemeYap(10, "Kart"); masa1.toplamBorcGoster(); masa2.toplamBorcGoster(); // tekrar sipariş veriliyor masa2.siparisVer(lahmacun); masa2.toplamBorcGoster(); } } |
Bunlara da Göz Atmak İsteyebilirsiniz.
<<< Önceki: Java Pass by Value – Pass by Reference ve İstisnalar
Sonraki: Java – Regular Expressions (Düzenli İfadeler) >>>
Yorum Bırakın!