C# Kalıtım (Inheritance)

Leader-TR

Üye
11 Ağu 2018
182
50
Sanane

Kalıtım (Inheritance)

Bir sınıfa ait özelliklerin başka bir sınıfa aktarılmasına kalıtım denir. Kalıtım bize kolaylık, performans ve verimlilik sağlar. Inheritance'nin amacı aynı özelliklere sahip sınıfların özelliklerini tekrar tekrar tanımlamaktansa, ortak özelliklere sahip temel bir sınıf oluşturup diğer sınıfların bu temel sınıfı miras almasını sağlamaktır. Kalıtımda iki sınıf türü bulunur bu sınıflar; temel(base/parent) sınıf ve türetilmiş(derived/child) sınıftır.

Temel (base/parent) Sınıf ve Türetilmiş (derived/child) Sınıf

Temel sınıf kendinden üretilen sınıflara referans olan ve alanını(field), özelliklerini(property), metodlarını kullandıran sınıf türüdür. Türetilmiş sınıf ise temel sınıftan türeyen ve bu özellikleri kullanan sınıf türüdür.
C#:
public class Kisi
{
    private string ad;
    private string soyad;
    private double boy;
    private string cinsiyet;

    public string Ad
    {
        get { return ad; }
        set { ad = value; }
    }
    public string Soyad
    {
        get { return soyad; }
        set { soyad = value; }
    }
    public double Boy
    {
        get { return boy; }
        set { boy = value; }
    }
    public string Cinsiyet
    {
        get { return cinsiyet; }
        set { cinsiyet = value; }
    }

    public void BilgiGöster()
    {
        System.Console.WriteLine("Tanımlanan kişinin adı: {0}, soyadı: {1}, boyu: {2}, cinsiyeti: {3}", Ad, Soyad, Boy, Cinsiyet);
    }
}

public class Personel : Kisi
{
    private int personelNo;
    private double maas;
    private string bolum;

    public int PersonelNO { get => personelNo; set => personelNo = value; }
    public double Maas { get => maas; set => maas = value; }
    public string Bolum { get => bolum; set => bolum = value; }
}

Miras alma işlemi class MirasAlanSınıfAdı : MirasAlınacakSınıfAdı şeklinde : operatörü sayesinde gerçekleşir. Temel sınıftaki yapıların miras alınabilmesi için public erişim belirleyicisi ile tanımlanmış olması gerekir. Burada Kişi sınıf temel sınıf, Personel sınıfı ise Kişi sınıfından türetilmiş bir sınıftır. Personel sınıf, Kişi sınıfından ad, soyad, boy, cinsiyet özelliklerini kendine katmıştır. Bunun mantığı her personel aslında bir kişi olduğundan kişinin özelliklerini barındırır.
Sınıfların dışında record'lar da kendi aralarında kalıtım alabilmektedir. Tek bir istisnai durum vardır oda sadece object türü sınıflardan kalıtım almasıdır. Yani record'ların kalıtım aldığı tek sınıf türü object türü sınıflardır.

Bir class yanlızca tek base class'tan türeyebilir, yanı birden fazla class'tan türeyemez ve sadece bir adet base class'ı olabilir. Örnek:
C#:
class Program
{
    static void Main(string[] args)
    {
        C c = new C();
        c.K = 4;
    }
}

class A
{
    public int a;
    public int K { get; set; }
}

class B : A
{
    public int S { get; set; }
}

class C : B
{
       
}

Yukarıda C sınıfı B'den, B sınıfı A'dan kalıtım almaktadır. Bunun sonucundan C sınıfından tanımlanmış bir nesne A sınıfındaki özelikleri de miras alır.
Burada nesne yapısını oluştururken ilk önce A classın'da ki nesneyi üretir, sonra B ve en son olarak C yapısındaki nesneyi üretir.

C#:
class Program
{
    static void Main(string[] args)
    {
        C c = new C();
    }
}

class A
{
    public A()
    {
        Console.WriteLine("{0} Constructor'u çalıştı.", nameof(A));
    }
       
}

class B : A
{
    public B()
    {
        Console.WriteLine("{0} Constructor'u çalıştı.", nameof(B));
    }
}

class C : B
{
    public C()
    {
        Console.WriteLine("{0} Constructor'u çalıştı.", nameof(C));
    }
}

Kod:
A Constructor'u çalıştı.
B Constructor'u çalıştı.
C Constructoru'u çalıştı.

C Constructoru'u çalıştı.
Gördüğünüz gibi önce A class'ı sonra B en son ise C class'ının constructor'u çalıştı.
Buradaki nameof() kodu, bulunduğu sınıfın ismini vermektedir.

Temel(base) Class Constructor'ını Çağırma

Kalıtımla türetilen sınıfın kurucu metodundan, temel sınıfın kurucu metoduna erişim sağlanabilir. Bu erişimi sağlayabilmek için base() keywordünü kullanmalıyız.

base() keywordünü base class'ının constructor metodu parametre aldığında kullanırız, parametresiz constructor metodu class miras alındığında zaten otomatik olarak çağrılmaktadır.
Yani base() keywordünü constructor metoda parametre vermek için kullanırız ve base classta birden fazla constructor metod var ise hangisinin tetikleneceğini base() keywordü sayesinde seçeriz.
Base class'ın constructor'u parametre alıyor ise derived(türetilmiş) classın constructor'ünde base() keyword'ü ile parametre vermek zorundayız. Ayrıca derived(türetilmiş) class'tan base class'daki public olan verilere ulaşmak için base keywordünü kullanabiliriz, ve son olara derived(türetilmiş) class verileri miras aldığından aynı verilere this keywordü ile de ulaşabiliriz ama bu keywordleri kullanmak zorunda değiliz. Yani bunları kullanmadan da verilere ulaşabiliriz.

C#:
class Program
{
    static void Main(string[] args)
    {
        Ogrenci ogr1 = new Ogrenci();
        Ogrenci ogr2 = new Ogrenci("Parametre alan temel sınıf kucuru metodu çalıştı.");

        Console.ReadLine();
    }
}

public class Kisi
{
    public int x { get; set; }
    public Kisi()
    {
        Console.WriteLine("Temel sınıf kurucu metodu çalıştı.");
    }

    public Kisi(string parametre)
    {
        Console.WriteLine(parametre);
    }

}

public class Ogrenci : Kisi
{
    public Ogrenci() : base() { }
    public Ogrenci(string parametre) : base(parametre) { }
    base.x = 20;
}

Kod:
Temel sınıf kurucu metodu çalıştı.
Parametre alan temel sınıf kucuru metodu çalıştı.

Burada ogr1 adında Ogrenci sınıfına ait bir nesne tanımladık. Nesneyi tanımlarken parametre vermediğimiz için Ogrenci sınıfının public Ogrenci() : base() { } kurucu metodu çalıştı ve bu kurucu metod base() { } ile Kişi sınıfının kurucu metodunu yani parametresiz olan public Kisi() metodunu kalıtım aldı.

Not: C#'da bütün sınıflar Object sınıfından kalıtım almaktadır. Yani Object sınıfından türetilmektedir. Başka sınıflardan kalıtım alan sınıflar ise dolaylı yoldan Object sınıfının özellikleri alır. Equals, GetType, ToString, GetHashCode metodları buradan gelmektedir.

Name Hiding

Name Hiding durumu base class'tan kalıtım alan herhangi bir class'ın aynı isimde üyelere sahip olmasıdır.
C#:
class MyClass1
{
    public int A { get; set; }
}

class MyClass2 : MyClass1
{
    public int A { get; set; }
}

Böyle bir durumda A property'sine ulaşmak istediğimizde base class'daki property saklanacak, onun yerine derived(türemiş) sınıftaki property'e ulaşacağız.
Bu durumda derleyci sadece bir uyarı mesajı verecektir. Geçmiş yıllarda Name Hiding yaparken new operatörünü kullanmak zorunluydu ama artık böyle bir zorunluluk yok.

C#:
class MyClass1
{
    public int A { get; set; }
}

class MyClass2 : MyClass1
{
    public new int A { get; set; }
}

new ile işaretlediğimiz durumda bir uyarı mesajı almayacağız.

aq3u4ls.png
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.