Clear        


                
                    using _07_Interfaces.Demos.Sekiller;
using _07_Interfaces.Models;

namespace _07_Interfaces
{
    internal class Program
    {
        // Interface'ler implemente edilecekleri (taşıdıkları özellik veya methodların uygulandığı ve kodlarının yazıldığı)
        // class veya class'lar için bir protokol (özellik veya methodlar üzerinden uygulama kuralı) niteliği
        // taşıyan abstract (soyut) yapılardır.
        // Interface'ler için kendisini implemente edecek tüm class veya class'lar için içerisinde özellik veya method tanımlarını
        // içeren bir base (temel) taslak veya arayüz de denebilir, bu yüzden genelde Bases klasöründe oluşturulur.
        // Interface'ler tek başına bir anlam ifade etmez ve abstract (soyut) oldukları için new'lenemez, sadece somut olan
        // class'lar new'lenebilir.
        // Interface'ler 'I' ile başlayarak tanımlanır.
        // Interface'ler içerisinde genelde tam olarak özellikler tanımlanmaz, methodlarınsa sadece tanım imzaları yazılır
        // (methodun içerisi doldurulmaz).
        // Interface'ler objeler arası bağımlılıkları minimize etmek için kullanılan birinci abstract yapıdır.
        // Object Oriented Programming'de (Nesneye Yönelik Programlama) objeler arasındaki bağımlılıklar gevşek olmalıdır
        // (Loose Coupling), tam tersi olan sıkı bağımlılık (Tight Coupling) tercih edilmemelidir.
        // Interface'ler N-Layer (N-Tier) Architecture'da (Çok Katmanlı Mimari) yoğun bir şekilde kullanılan birinci abstract yapıdır.
        // Amaç katmanlar arası bağımlılıkları minimize etmektir.
        // Interface'ler daha çok verileri yöneten (repository) veya iş yapan (service veya manager) class'larında kullanıldıklarından
        // method tanımları üzerinden daha sık kullanılır.
        // Kodlar okunurken class'lar bir interface'dir şeklinde okunur (örneğin Ogrenci bir IKisi'dir).



        static void Main(string[] args)
        {
            //IKisi kisi = new IKisi(); // interface'ler abstract olduklarından new'lenemez



            Ogrenci ogrenci1 = new Ogrenci() // Ogrenci class'ı concrete olduğundan new'lenebilir, referans değişkeninin (ogrenci1)
                                             // tipi de Ogrenci olarak tanımlanabilir,
                                             // genelde içerisinde sadece veri tutan Entity'ler, Model'ler veya DTO'lar bu şekilde new'lenir
            {
                TcKimlikNo = "12345678901",
                Adi = "Luna",
                Soyadi = "Alsaç",
                Okulu = "Sheltie Üniversitesi"
            };
            Console.WriteLine(ogrenci1.Getir());

            Console.WriteLine();



            IKisi ogrenci2 = new Ogrenci() // referans değişken tipi interface, obje tipi class olacak şekilde new'leme yapılabilir,
                                           // şu anda ogrenci2 referans değişkeni Leo adı özelliğine sahip objeyi refere etmektedir,
                                           // IKisi tipindeki referans değişkeni üzerinden Ogrenci tipindeki (class) objeyi new'lerken
                                           // özelliklerini atıyoruz,
                                           // obje new'lenirken Ogrenci tipi kullanıldığından Ogrenci'nin tüm özellikleri kullanılabilir
            {
                TcKimlikNo = "98765432101",
                Adi = "Leo",
                Soyadi = "Alsaç",
                Okulu = "Sheltie Üniversitesi"
            };
            Console.WriteLine(ogrenci2.Getir());

            Console.WriteLine();



            IKisi ogrenci3 = new Ogrenci(); // şu anda ogrenci3 referans değişkeni Angel adı özelliğine sahip objeyi refere etmektedir,
                                            // önce IKisi tipindeki referans değişkeni üzerinden Ogrenci tipindeki objeyi new'liyoruz

            // daha sonra obje özelliklerini set ediyoruz
            ogrenci3.TcKimlikNo = "11122233344"; // bu özellik IKisi tipindeki interface'de tanımlı olduğu için kullanılabilir
            ogrenci3.Adi = "Angel"; // bu özellik IKisi tipindeki interface'de tanımlı olduğu için kullanılabilir
            ogrenci3.Soyadi = "Alsaç"; // bu özellik IKisi tipindeki interface'de tanımlı olduğu için kullanılabilir

            //ogrenci3.Okulu = "İrlanda Seteri Üniversitesi"; // bu özellik IKisi tipindeki interface'de tanımlı olmadığı için kullanılamaz

            Console.WriteLine(ogrenci3.Getir()); // ogrenci3'ün okulunu yukarıda atayamadığımızdan boş gelecektir

            // Console.WriteLine("Öğrenci 3 Okulu: " + ogrenci3.Okulu); // aynı şekilde Okulu IKisi interface'inde tanımlı olmadığı için kullanılamaz

            Console.WriteLine();



            // ogrenci2 referans değişkeni üzerinden objeyi new'lerken okulunu set etmiştik, ancak ogrenci2'nin tipi
            // IKisi olduğu için ve içerisinde okulu özelliği bulunmadığından obje üzerinden bu özelliği kullanamayız

            //Console.WriteLine("Öğrenci 2 Okulu: " + ogrenci2.Okulu);

            // ancak ogrenci2 objemizde okulu özelliğindeki veriye casting (birbirlerine uyumlu tipleri dönüştürme) üzerinden ulaşabiliriz

            Console.WriteLine("Öğrenci 2 Okulu: " + ((Ogrenci)ogrenci2).Okulu); // casting 1. yöntem
            Console.WriteLine("Öğrenci 2 Okulu: " + (ogrenci2 as Ogrenci).Okulu); // casting 2. yöntem

            Console.WriteLine();



            Musteri museri1 = new Musteri() // hem referans değişken tipi hem de obje tipi aynı olduğundan tüm özellikleri kullanabiliyoruz
            {
                Adi = "Çağıl",
                Soyadi = "Alsaç",
                KrediKartiNo = "9876 5432 1098 7654",
                TcKimlikNo = "11199922288"
            };

            Console.WriteLine(museri1.Getir());

            Console.WriteLine();



            IKisi musteri2 = new Musteri() // bu sefer objenin tipi Musteri, referans değişkeninin tipi IKisi,
                                           // ancak yine tüm özellikleri objeyi new'lerken kullanabiliriz
            {
                Adi = "Ali",
                Soyadi = "Veli",
                KrediKartiNo = "1928 3746 5463 7281",
                TcKimlikNo = "55511199946"
            };

            Console.WriteLine(musteri2.Getir()); // musteri2'nin class içerisindeki özellikleri üzerinden çalışan method ile
                                                 // tüm verileri dolu gelecektir

            //Console.WriteLine("Müşteri 2 Kredi Kartı No: " + musteri2.KrediKartiNo); // IKisi interface'inde KrediKartiNo
                                                                                       // özelliği olmadığı için kullanamayız

            // ancak casting ile objede saklanan kredi kart numarası verisine ulaşabiliriz

            Console.WriteLine("Müşteri 2 Kredi Kartı No: " + (musteri2 as Musteri).KrediKartiNo);

            Console.WriteLine();



            #region Demos
            SekillerDemo.Calistir();
            #endregion
        }
    }
}