Altbilgi içeriğine atla
Iron Academy Logo
C# öğrenin
C# öğrenin

Diğer Kategoriler

C# OOP'yi Anlamak

Tim Corey
49m 41s

Kalıtım ve arayüzler, nesne yönelimli programlamanın (OOP) ayrılmaz parçalarıdır. Tim Corey, "C#'ta Kalıtım ile Arayüzler: Nesne Yönelimli Programlama" videosunda, kalıtımı ne zaman kullanmanız gerektiğini ve arayüzleri ne zaman tercih etmeniz gerektiğini detaylı bir şekilde açıklar.

Bu makale, Tim Corey'nin videosuna yönelik kapsamlı bir kılavuz olarak hizmet eder. Videodaki ana kavramları, örnekleri ve kod açıklamalarını bölerek, kalıtım ve arayüzler arasındaki farkları ve ne zaman her birini kullanmanız gerektiğini vurgular.

Giriş

Tim, (0:00) itibariyle kalıtım ve arayüzler arasındaki ayrımı yapmanın önemini vurgulayarak başlar. Her bir kavramın ne zaman kullanılması gerektiğini anlamanın, en iyi sonuçları elde etme gerekliliğine dikkat çeker. Amacı, yanlış tekli kalıtım kullanımını örneklerle gösterip ardından düzeltmektir.

Projeyi Oluşturma

Tim, (1:08)'de .NET 5 kullanarak basit bir konsol uygulaması oluşturur. Projeye 'OODemoApp' adını verir ve öncelikli hedefin konseptleri göstermek olduğunu üretim seviyesinde kod oluşturmak olmadığını açıklar.

Kalıtıma Dair Anlayış

Tim, 1:55'te, kalıtımın temellerine dalar. Kalıtımın, bir temel sınıfın özellik ve yöntemlerinin türetilmiş bir sınıf tarafından miras alındığı bir mekanizma olarak tanımlar. Kalıtımın salt kod yeniden kullanımı ve paylaşımı için değil, mantıksal bir "is-a" ilişkisi kurmak için kullanılmaması gerektiğini vurgular.

Ana noktalar:

  • Is-a İlişkisi: Türetilmiş sınıfın temel sınıfın bir türü olmasını sağlar.
  • Ortak Mantık: Kalıtılmış sınıflar yalnızca özellikler veya yöntem imzaları değil, ortak bir mantık paylaşmalıdır.

Örnek Sınıf: Kiralık Araba

Tim, 7:52'de kalıtımın temel konseptini açıklamak için bir RentalCar sınıfı oluşturur. Bu sınıf, Miami, Florida'daki bir kiralık araç ajansında bir kiralık arabayı temsil eder.

public class RentalCar
{
    public int RentalId { get; set; }
    public string CurrentRenter { get; set; }
    public decimal PricePerDay { get; set; }
    public int NumberOfPassengers { get; set; }

    public void StartEngine()
    {
        Console.WriteLine("Turn key to ignition setting");
        Console.WriteLine("Turn key to on");
    }

    public void StopEngine()
    {
        Console.WriteLine("Turn key to off");
    }
}
public class RentalCar
{
    public int RentalId { get; set; }
    public string CurrentRenter { get; set; }
    public decimal PricePerDay { get; set; }
    public int NumberOfPassengers { get; set; }

    public void StartEngine()
    {
        Console.WriteLine("Turn key to ignition setting");
        Console.WriteLine("Turn key to on");
    }

    public void StopEngine()
    {
        Console.WriteLine("Turn key to off");
    }
}

Yanlış Kalıtımın Açmazlarını Gösterme

Tim, 10:15'de kalıtımın yanlış kullanılmasının nasıl sorunlara yol açabileceğini açıklar. Kalıtımın yanlış kullanılması durumunda yönetilmesi ve genişletilmesi zor bir kod yapısına yol açabileceğine dikkat çeker. Kalıtımı sadece kod paylaşımı için kullanmayı tavsiye etmez.

Araba ve Kamyon Türleri için Enumlar Ekleme

Tim, 10:45'te araba türlerini ayırt etmek için bir enum ekler. Tüm enumları tek bir yerde tutmak için Enums.cs adında yeni bir sınıf dosyası oluşturur. Bu enum, farklı araba stillerini ayırt etmede yardımcı olacaktır.

// Enums.cs
public enum CarType
{
    Hatchback,
    Sedan,
    Compact
}
// Enums.cs
public enum CarType
{
    Hatchback,
    Sedan,
    Compact
}

Ardından, RentalCar sınıfına bir araba türünü belirtmek için bir özellik ekler.

public class RentalCar : RentalVehicle
{
    public CarType Style { get; set; }
    // Other properties and methods
}
public class RentalCar : RentalVehicle
{
    public CarType Style { get; set; }
    // Other properties and methods
}

Kamyon Dahil Etme

12:27'de Tim, kiralık ajansın filolarına kamyon eklemeye karar verdiğini açıklayarak, nye ihtiyaç duyulduğunu belirtir. RentalVehicle ana sınıfından türetilerek yeni bir RentalTruck sınıfı oluşturur.

public class RentalTruck : RentalVehicle
{
    public TruckType Style { get; set; }
    // Other properties and methods
}
public class RentalTruck : RentalVehicle
{
    public TruckType Style { get; set; }
    // Other properties and methods
}

Ardından, kamyon türleri için yeni bir enum tanımlar.

// Enums.cs
public enum TruckType
{
    ShortBed,
    LongBed
}
// Enums.cs
public enum TruckType
{
    ShortBed,
    LongBed
}

Farklı Mülk Türlerini Yönetme

15:28'de Tim, iki mülk aynı ismi paylaştığında onların aynı olduğunu varsaymanın yanlış olacağını vurgular. Bunu, araba ve kamyonlar için farklı enumlar (araba türleri için CarType ve kamyon türleri için TruckType) ile gösterecektir.

Filo için Tekneleri Tanıtma

Kiralık ajans filosunu tekneleri de içerecek şekilde genişletir. Tim bunu bir RentalBoat sınıfı oluşturarak nasıl yöneteceğini gösterir. İlk başta, tekneler bazı özellikleri arabalar ve kamyonlarla paylaşabileceğinden, yönetilebilir gibi görünüyor.

public class RentalBoat : RentalVehicle
{
    // Properties and methods specific to boats
}
public class RentalBoat : RentalVehicle
{
    // Properties and methods specific to boats
}

Yelkenli Teknelerle Uğraşma

Yelkenli teknelerin tanıtılması, motorları olmadığı için bir zorluk oluşturur. Tim, 19:57'de bu senaryoda kalıtımın sınırlamalarını örnekler.

public class RentalSailboat : RentalVehicle
{
    public override void StartEngine()
    {
        throw new NotImplementedException("I do not have an engine to start");
    }

    public override void StopEngine()
    {
        throw new NotImplementedException("I do not have an engine to stop");
    }
}
public class RentalSailboat : RentalVehicle
{
    public override void StartEngine()
    {
        throw new NotImplementedException("I do not have an engine to start");
    }

    public override void StopEngine()
    {
        throw new NotImplementedException("I do not have an engine to stop");
    }
}

Arayüzlerle Sorunu Çözme

Tim, base sınıfında StartEngine ve StopEngine yöntemlerini sanal yapmayı önerir, böylece türetilmiş sınıflarda bu yöntemlerin kullanılmadığı durumlarda geçersiz kılınabilirler.

public abstract class RentalVehicle
{
    // Common properties

    public virtual void StartEngine()
    {
        Console.WriteLine("Engine started");
    }

    public virtual void StopEngine()
    {
        Console.WriteLine("Engine stopped");
    }
}
public abstract class RentalVehicle
{
    // Common properties

    public virtual void StartEngine()
    {
        Console.WriteLine("Engine started");
    }

    public virtual void StopEngine()
    {
        Console.WriteLine("Engine stopped");
    }
}

Çağrılmaması Gereken Yöntemlerle Başa Çıkma

21:56'da Tim, miras alınmış sınıflarda çağrılmaması gereken yöntemlerin olmasının sıkıntılarını açıklar. Bir motoru olmayan RentalSailboat sınıfı örneğinde, RentalVehicle sınıfından StartEngine ve StopEngine yöntemlerini miras alır. Bu durum, bu yöntemlerin kazara çağrılması durumunda problem yaratabilir ve bu durumda, geçerli olmadıklarını göstermek için istisnalar atmaları gerekir.

public class RentalSailboat : RentalVehicle
{
    public override void StartEngine()
    {
        throw new NotImplementedException("I do not have an engine to start");
    }

    public override void StopEngine()
    {
        throw new NotImplementedException("I do not have an engine to stop");
    }
}
public class RentalSailboat : RentalVehicle
{
    public override void StartEngine()
    {
        throw new NotImplementedException("I do not have an engine to start");
    }

    public override void StopEngine()
    {
        throw new NotImplementedException("I do not have an engine to stop");
    }
}

Kalıtımın Sınırlamalarını Tanıma

Tim, 24:06'da, kalıtımın artık mantıklı görünmediği ve karışık bir kod tabanına yol açabileceği konusunda vurgu yapar. Örneğin, bir yelkenlinin bir RentalVehicle olarak düşünülmemesi gerektiğine işaret eder; bu kalıtımın sınırlamaları ve daha iyi bir tasarım yaklaşımının gerekliliğini gösterir.

Arayüzlerle Daha İyi Bir Tasarıma Geçiş

Bu sorunları ele almak için, Tim arayüzleri kullanarak daha iyi bir tasarımı önerir. Geliştirilmiş yaklaşımı göstermek için 'BetterOODemo' adında bir yeni konsol uygulaması projesi oluşturarak başlar.

Arayüzü Tanımlama

Tim, tüm kiralananların ortak özelliklerini kapsayacak şekilde IRental arayüzünü tanıtır.

public interface IRental
{
    int RentalId { get; set; }
    string CurrentRenter { get; set; }
    decimal PricePerDay { get; set; }
}
public interface IRental
{
    int RentalId { get; set; }
    string CurrentRenter { get; set; }
    decimal PricePerDay { get; set; }
}

Kara Araçları için Temel Sınıf Oluşturma

Tim daha sonra kara araçları için bir temel sınıf oluşturur ve araç kiralama konseptini aracı kendisinden ayırır.

public abstract class LandVehicle
{
    public int NumberOfPassengers { get; set; }

    public virtual void StartEngine()
    {
        Console.WriteLine("Engine started");
    }

    public virtual void StopEngine()
    {
        Console.WriteLine("Engine stopped");
    }
}
public abstract class LandVehicle
{
    public int NumberOfPassengers { get; set; }

    public virtual void StartEngine()
    {
        Console.WriteLine("Engine started");
    }

    public virtual void StopEngine()
    {
        Console.WriteLine("Engine stopped");
    }
}

Temel araç sınıfının adını LandVehicle olarak değiştirerek, sadece uygun araçların motorla ilgili yöntemleri miras almasını sağlar.

Araba ve Kamyon Sınıflarını Uygulama

Tim, LandVehicle'den türeyen ve IRental arayüzünü uygulayan Car ve Truck sınıflarını oluşturur.

public class Car : LandVehicle, IRental
{
    public int RentalId { get; set; }
    public string CurrentRenter { get; set; }
    public decimal PricePerDay { get; set; }
    public CarType Style { get; set; }
}

public class Truck : LandVehicle, IRental
{
    public int RentalId { get; set; }
    public string CurrentRenter { get; set; }
    public decimal PricePerDay { get; set; }
    public TruckType Style { get; set; }
}
public class Car : LandVehicle, IRental
{
    public int RentalId { get; set; }
    public string CurrentRenter { get; set; }
    public decimal PricePerDay { get; set; }
    public CarType Style { get; set; }
}

public class Truck : LandVehicle, IRental
{
    public int RentalId { get; set; }
    public string CurrentRenter { get; set; }
    public decimal PricePerDay { get; set; }
    public TruckType Style { get; set; }
}

Bu tasarım, her sınıfın yalnızca kendi türüyle ilgili özelliklere ve yöntemlere sahip olmasını sağlayarak açık bir sorumluluk ayrımını korur.

Kod Çoğaltımından Kaçınma

Tim, gereksiz kod tekrarından kaçınmanın önemini 31:41'de tartışıyor. IRental arayüzü, aynı özellikleri birden fazla sınıfta gerektirse de, gerçekte bu, DRT (Don't Repeat Yourself - Kendini Tekrarlama) ilkesinin ihlali olarak kabul edilmez çünkü hiçbir mantık tekrar edilmez; yalnızca özellik bildirimleri.

Rental Sailboat Sınıfını Uygulama

Tim, 35:09'da RentalSailboat sınıfının, LandVehicle'den türetmek yerine IRental arayüzünü uygulayarak ayrı olarak nasıl ele alınacağını açıklar. Bu yaklaşım, uygunsuz kalıtım ile ilişkili tuzaklardan kaçınmaya yardımcı olur.

public class Sailboat : IRental
{
    public int RentalId { get; set; }
    public string CurrentRenter { get; set; }
    public decimal PricePerDay { get; set; }

    // Additional properties and methods specific to sailboats
}
public class Sailboat : IRental
{
    public int RentalId { get; set; }
    public string CurrentRenter { get; set; }
    public decimal PricePerDay { get; set; }

    // Additional properties and methods specific to sailboats
}

Farklı Kiralamaları Yönetme

Tim, farklı türde kiralamaları yönetmek için IRental arayüzünü kullanarak kamyonlar, yelkenliler ve arabalar dahil olmak üzere çeşitli kiralama türlerini depolamak için bir liste oluşturur.

List<IRental> rentals = new List<IRental>
{
    new Truck { CurrentRenter = "Truck Renter" },
    new Sailboat { CurrentRenter = "Sailboat Renter" },
    new Car { CurrentRenter = "Car Renter" }
};
List<IRental> rentals = new List<IRental>
{
    new Truck { CurrentRenter = "Truck Renter" },
    new Sailboat { CurrentRenter = "Sailboat Renter" },
    new Car { CurrentRenter = "Car Renter" }
};

Bu tasarım, kiralamalar arasında dönüp CurrentRenter, PricePerDay ve RentalId gibi ortak özelliklere erişim imkânı tanır.

foreach (var rental in rentals)
{
    Console.WriteLine($"Renter: {rental.CurrentRenter}, Price Per Day: {rental.PricePerDay}");
}
foreach (var rental in rentals)
{
    Console.WriteLine($"Renter: {rental.CurrentRenter}, Price Per Day: {rental.PricePerDay}");
}

Belirli Türlere Dönüştürme

Farklı kiralama türlerinin belirli özelliklerine ve yöntemlerine erişmek için, Tim, nesneleri kendi türlerine kontrol etmek ve dönüştürmek amacıyla is anahtar kelimesinin nasıl kullanılacağını gösterir.

foreach (var rental in rentals)
{
    if (rental is Truck truck)
    {
        Console.WriteLine($"Truck Style: {truck.Style}, Passengers: {truck.NumberOfPassengers}");
    }
    else if (rental is Sailboat sailboat)
    {
        // Access sailboat-specific properties
    }
    else if (rental is Car car)
    {
        // Access car-specific properties
    }
}
foreach (var rental in rentals)
{
    if (rental is Truck truck)
    {
        Console.WriteLine($"Truck Style: {truck.Style}, Passengers: {truck.NumberOfPassengers}");
    }
    else if (rental is Sailboat sailboat)
    {
        // Access sailboat-specific properties
    }
    else if (rental is Car car)
    {
        // Access car-specific properties
    }
}

Arayüzlerle Esneklik

Tim, gelecekteki değişiklikler için esneklik sağladığını vurgular. Örneğin, tanklar veya TV'ler gibi yeni kiralama türleri eklemek mevcut yapıyı bozmaz.

Kalıtımın Aşırı Kullanımından Kaçınma

Tim, kalıtımı kod paylaşımı için aşırı kullanmamaya dikkat çeker çünkü bu, karmaşık ve esneklikten yoksun bir kod tabanına yol açabilir. Bunun yerine, arayüzleri ve bileşimi kullanarak istenen sonuçlara ulaşmayı, "is-a" ilişkisinin mantıksal sınırlarını aşmadan önerir.

Sonuç

Tim Corey'in OOP'de kalıtım ve arayüzleri açıklaması, bakım yapabilir ve esnek kod oluşturmak için net bir yol sunar. Ortak tuzakları sergileyerek ve arayüzlerle rafine bir tasarım sunarak, geliştiricilerin uygulamalarını etkili bir şekilde yapılandırma konusunda bilinçli kararlar almasını sağlar.

Bu kavramlara daha derinlemesine dalmak ve bunları eylemde görmek için Tim'in tam videosunu izleyin. Onun kanalı, programlama eğitimleri açısından bir altından madeni. Kaçırmayın!

Hero Worlddot related to C# OOP'yi Anlamak
Hero Affiliate related to C# OOP'yi Anlamak

Sevdiğiniz Şeyleri Paylaşarak Daha Fazla Kazanın

.NET, C#, Java, Python veya Node.js ile çalışan geliştiriciler için içerik oluşturuyor musunuz? Uzmanlığınızı ek gelire dönüştürün!

Iron Destek Ekibi

Haftada 5 gün, 24 saat çevrimiçiyiz.
Sohbet
E-posta
Beni Ara