Sınıflar ve nesnelerle nesne odaklı programlamayı keşfetme

Bu öğreticide bir konsol uygulaması oluşturacak ve C# dilinin parçası olan temel nesne odaklı özellikleri göreceksiniz.

Önkoşullar

  • Windows veya Mac için Visual Studio'yu öneririz. Visual Studio indirmeleri sayfasından ücretsiz bir sürüm indirebilirsiniz. Visual Studio ,NET SDK'sını içerir.
  • Visual Studio Code düzenleyicisini de kullanabilirsiniz. En son .NET SDK'sını ayrıca yüklemeniz gerekir.
  • Farklı bir düzenleyici tercih ediyorsanız en son .NET SDK'sını yüklemeniz gerekir.

Uygulamanızı oluşturma

Terminal penceresi kullanarak Classes adlı bir dizin oluşturun. Uygulamanızı orada oluşturacaksınız. Bu dizine geçin ve konsol penceresine yazın dotnet new console . Bu komut uygulamanızı oluşturur. Program.cs dosyasını açın. Şu şekilde görünmelidir:

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

Bu öğreticide, bir banka hesabını temsil eden yeni türler oluşturacaksınız. Genellikle geliştiriciler her sınıfı farklı bir metin dosyasında tanımlar. Bu, bir programın boyutu büyüdükçe yönetimi kolaylaştırır. Sınıflar dizininde BankAccount.cs adlı yeni bir dosya oluşturun.

Bu dosya bir banka hesabının tanımını içerir. Nesne Odaklı programlama, sınıf biçiminde türler oluşturarak kodu düzenler. Bu sınıflar belirli bir varlığı temsil eden kodu içerir. BankAccount sınıfı bir banka hesabını temsil eder. Kod, yöntemler ve özellikler aracılığıyla belirli işlemleri uygular. Bu öğreticide banka hesabı şu davranışı destekler:

  1. Banka hesabını benzersiz olarak tanımlayan 10 basamaklı bir sayıya sahiptir.
  2. Sahiplerin adını veya adlarını depolayan bir dizeye sahiptir.
  3. Bakiye alınabilir.
  4. Depozitoları kabul ediyor.
  5. Para çekmeyi kabul eder.
  6. İlk bakiye pozitif olmalıdır.
  7. Para çekme işlemleri negatif bakiyeye neden olamaz.

Banka hesabı türünü tanımlama

Bu davranışı tanımlayan bir sınıfın temellerini oluşturarak başlayabilirsiniz. Dosya:Yeni komutunu kullanarak yeni bir dosya oluşturun. BankAccount.cs olarak adlandır. BankAccount.cs dosyanıza aşağıdaki kodu ekleyin:

namespace Classes;

public class BankAccount
{
    public string Number { get; }
    public string Owner { get; set; }
    public decimal Balance { get; }

    public void MakeDeposit(decimal amount, DateTime date, string note)
    {
    }

    public void MakeWithdrawal(decimal amount, DateTime date, string note)
    {
    }
}

Devam etmeden önce, ne oluşturduğunuza bir göz atalım. Bildirimi, namespace kodunuzu mantıksal olarak düzenlemek için bir yol sağlar. Bu öğretici nispeten küçük olduğundan tüm kodu tek bir ad alanına yerleştireceksiniz.

public class BankAccount oluşturduğunuz sınıfı veya türü tanımlar. içindeki ve içindeki { ve } sınıf bildirimini izleyen her şey, sınıfın durumunu ve davranışını tanımlar. Sınıfın BankAccount beş üyesi vardır. İlk üçü özelliklerdir. Özellikler veri öğeleridir ve doğrulamayı veya diğer kuralları zorlayan kodlara sahip olabilir. Son ikisi yöntemlerdir. Yöntemler, tek bir işlev gerçekleştiren kod bloklarıdır. Üyelerin her birinin adlarını okumak, sınıfın ne yaptığını anlamak için size veya başka bir geliştiriciye yeterli bilgi sağlamalıdır.

Yeni hesap açma

Uygulanacak ilk özellik bir banka hesabı açmaktır. Müşteri bir hesap açtığında, bir ilk bakiye ve bu hesabın sahibi veya sahipleri hakkında bilgi sağlamalıdır.

Türünde yeni bir nesne BankAccount oluşturmak, bu değerleri atayan bir oluşturucu tanımlamak anlamına gelir. Oluşturucu, sınıfıyla aynı ada sahip bir üyedir. Bu sınıf türüne ait nesneleri başlatmak için kullanılır. Türüne aşağıdaki oluşturucuyu BankAccount ekleyin. Aşağıdaki kodu bildiriminin MakeDepositüzerine yerleştirin:

public BankAccount(string name, decimal initialBalance)
{
    this.Owner = name;
    this.Balance = initialBalance;
}

Yukarıdaki kod, niteleyiciyi ekleyerek oluşturmakta olan nesnenin this özelliklerini tanımlar. Bu niteleyici genellikle isteğe bağlıdır ve atlanır. Ayrıca şunları da yazabilirdiniz:

public BankAccount(string name, decimal initialBalance)
{
    Owner = name;
    Balance = initialBalance;
}

Niteleyici this yalnızca yerel bir değişken veya parametre bu alan veya özellik ile aynı ada sahip olduğunda gereklidir. this Gerekli olmadığı sürece bu makalenin geri kalanında niteleyici atlanır.

kullanarak bir nesne oluşturduğunuzda oluşturucular çağrılır new. Program.cs içindeki satırı Console.WriteLine("Hello World!"); aşağıdaki kodla değiştirin (yerine adınızı yazın<name>):

using Classes;

var account = new BankAccount("<name>", 1000);
Console.WriteLine($"Account {account.Number} was created for {account.Owner} with {account.Balance} initial balance.");

Şimdiye kadar inşa ettiğiniz şeyi çalıştıralım. Visual Studio kullanıyorsanız Hata Ayıkla menüsünden Hata ayıklama olmadan başlat'ı seçin. Komut satırı kullanıyorsanız, projenizi oluşturduğunuz dizini yazın dotnet run .

Hesap numarasının boş olduğunu fark ettiniz mi? Bunu düzeltmenin zamanı geldi. Nesne oluşturulduğunda hesap numarası atanmalıdır. Ancak bunu oluşturmak çağıranın sorumluluğunda olmamalıdır. Sınıf kodu, BankAccount yeni hesap numaralarının nasıl atanması gerektiğini bilmelidir. Basit bir yol, 10 basamaklı bir sayı ile başlamaktır. Her yeni hesap oluşturulduğunda bunu artır. Son olarak, bir nesne oluşturulduğunda geçerli hesap numarasını depolayın.

sınıfına BankAccount bir üye bildirimi ekleyin. Aşağıdaki kod satırını, açılış ayracından { sonra sınıfın BankAccount başına yerleştirin:

private static int s_accountNumberSeed = 1234567890;

accountNumberSeed bir veri üyesidir. bu, privateyalnızca sınıfın BankAccount içindeki kodla erişilebileceği anlamına gelir. Bu, genel sorumlulukları (hesap numarasına sahip olmak gibi) özel uygulamadan (hesap numaralarının nasıl oluşturulduğu) ayırmanın bir yoludur. Ayrıca static, tüm nesneler tarafından BankAccount paylaşıldığı anlamına gelir. Statik olmayan bir değişkenin değeri nesnenin BankAccount her örneği için benzersizdir. accountNumberSeed bir private static alandır ve bu nedenle C# adlandırma kurallarına göre ön eke sahiptirs_. Açıklama s ve static_ açıklama private alanı. Hesap numarasını atamak için oluşturucuya aşağıdaki iki satırı ekleyin. Bunları yazan this.Balance = initialBalancesatırın arkasına yerleştirin:

Number = s_accountNumberSeed.ToString();
s_accountNumberSeed++;

Sonuçları görmek için yazın dotnet run .

Para yatırma ve çekme işlemleri oluşturma

Banka hesabı sınıfınızın doğru çalışması için para yatırma ve çekme işlemleri kabul etmesi gerekir. Hesap için yapılan her işlemin günlüğünü oluşturarak para yatırma ve çekme işlemlerini uygulayalım. Her işlemi izlemenin, her işlemdeki bakiyeyi güncelleştirmeye kıyasla birkaç avantajı vardır. Geçmiş, tüm işlemleri denetlemek ve günlük bakiyeleri yönetmek için kullanılabilir. Gerektiğinde tüm işlemlerin geçmişinden bakiyenin hesaplanması, düzeltilen tek bir işlemdeki hataların bir sonraki hesaplamada bakiyeye doğru şekilde yansıtılmasını sağlar.

Bir işlemi temsil etmek için yeni bir tür oluşturarak başlayalım. İşlem, herhangi bir sorumluluğu olmayan basit bir türdür. Birkaç özelliğe ihtiyacı vardır. Transaction.cs adlı yeni bir dosya oluşturun. Buna aşağıdaki kodu ekleyin:

namespace Classes;

public class Transaction
{
    public decimal Amount { get; }
    public DateTime Date { get; }
    public string Notes { get; }

    public Transaction(decimal amount, DateTime date, string note)
    {
        Amount = amount;
        Date = date;
        Notes = note;
    }
}

Şimdi sınıfına BankAccount bir List<T>Transaction nesne ekleyelim. BankAccount.cs dosyanızda oluşturucudan sonra aşağıdaki bildirimi ekleyin:

private List<Transaction> _allTransactions = new List<Transaction>();

Şimdi doğru hesaplayalım Balance. Geçerli bakiye, tüm işlemlerin değerleri toplanarak bulunabilir. Kod şu anda olduğu için hesabın yalnızca ilk bakiyesini alabilirsiniz, bu nedenle özelliği güncelleştirmeniz Balance gerekir. BankAccount.cs içindeki satırı public decimal Balance { get; } aşağıdaki kodla değiştirin:

public decimal Balance
{
    get
    {
        decimal balance = 0;
        foreach (var item in _allTransactions)
        {
            balance += item.Amount;
        }

        return balance;
    }
}

Bu örnekte özelliklerin önemli bir yönü gösterilmektedir. Şimdi başka bir programcı değeri istediğinde dengeyi hesaplıyorsunuz. Hesaplamanız tüm işlemleri numaralandırır ve toplamı geçerli bakiye olarak sağlar.

Ardından ve MakeWithdrawal yöntemlerini uygulayınMakeDeposit. Bu yöntemler son iki kuralı zorunlu tutar: ilk bakiye pozitif olmalı ve herhangi bir çekme işlemi negatif bakiye oluşturmamalıdır.

Bu kurallar özel durumlar kavramını tanıtır. Bir yöntemin çalışmasını başarıyla tamamlayabildiğini göstermenin standart yolu bir özel durum oluşturmaktır. Özel durum türü ve onunla ilişkilendirilmiş ileti hatayı açıklar. Burada, MakeDeposit depozito miktarı 0'dan büyük değilse yöntem bir özel durum oluşturur. Yöntem, MakeWithdrawal para çekme tutarı 0'dan büyük değilse veya para çekme işleminin uygulanması negatif bakiyeyle sonuçlanırsa bir istisna oluşturur. Listenin bildiriminden _allTransactions sonra aşağıdaki kodu ekleyin:

public void MakeDeposit(decimal amount, DateTime date, string note)
{
    if (amount <= 0)
    {
        throw new ArgumentOutOfRangeException(nameof(amount), "Amount of deposit must be positive");
    }
    var deposit = new Transaction(amount, date, note);
    _allTransactions.Add(deposit);
}

public void MakeWithdrawal(decimal amount, DateTime date, string note)
{
    if (amount <= 0)
    {
        throw new ArgumentOutOfRangeException(nameof(amount), "Amount of withdrawal must be positive");
    }
    if (Balance - amount < 0)
    {
        throw new InvalidOperationException("Not sufficient funds for this withdrawal");
    }
    var withdrawal = new Transaction(-amount, date, note);
    _allTransactions.Add(withdrawal);
}

deyimi throwbir özel durum oluşturur. Geçerli bloğun yürütülmesi sona erer ve çağrı yığınında bulunan ilk eşleşen catch bloğa aktarımları denetler. Bu kodu biraz sonra test etmek için bir catch blok ekleyeceksiniz.

Oluşturucu, bakiyeyi doğrudan güncelleştirmek yerine ilk işlemi ekleyebilmesi için bir değişiklik almalıdır. Yöntemini zaten yazdığınızdan MakeDeposit , oluşturucunuzdan çağırın. Tamamlanmış oluşturucu şöyle görünmelidir:

public BankAccount(string name, decimal initialBalance)
{
    Number = s_accountNumberSeed.ToString();
    s_accountNumberSeed++;

    Owner = name;
    MakeDeposit(initialBalance, DateTime.Now, "Initial balance");
}

DateTime.Now geçerli tarih ve saati döndüren bir özelliktir. Yeni bir BankAccountkod oluşturan kodu izleyerek yönteminize Main birkaç para yatırma ve çekme işlemi ekleyerek bu kodu test edin:

account.MakeWithdrawal(500, DateTime.Now, "Rent payment");
Console.WriteLine(account.Balance);
account.MakeDeposit(100, DateTime.Now, "Friend paid me back");
Console.WriteLine(account.Balance);

Ardından, negatif bakiyesi olan bir hesap oluşturmaya çalışarak hata koşullarını yakaladığınızı test edin. Az önce eklediğiniz önceki koddan sonra aşağıdaki kodu ekleyin:

// Test that the initial balances must be positive.
BankAccount invalidAccount;
try
{
    invalidAccount = new BankAccount("invalid", -55);
}
catch (ArgumentOutOfRangeException e)
{
    Console.WriteLine("Exception caught creating account with negative balance");
    Console.WriteLine(e.ToString());
    return;
}

Özel durumlar oluşturabilecek bir kod bloğunu işaretlemek ve beklediğiniz hataları yakalamak için deyimini kullanırsınız.try-catch Negatif bakiye için özel durum oluşturan kodu test etmek için aynı tekniği kullanabilirsiniz. yönteminizde Main bildiriminden invalidAccount önce aşağıdaki kodu ekleyin:

// Test for a negative balance.
try
{
    account.MakeWithdrawal(750, DateTime.Now, "Attempt to overdraw");
}
catch (InvalidOperationException e)
{
    Console.WriteLine("Exception caught trying to overdraw");
    Console.WriteLine(e.ToString());
}

Dosyayı kaydedin ve denemek için yazın dotnet run .

Sınama - tüm işlemleri günlüğe kaydetme

Bu öğreticiyi GetAccountHistory tamamlamak için işlem geçmişi için bir string oluşturan yöntemi yazabilirsiniz. Bu yöntemi türüne BankAccount ekleyin:

public string GetAccountHistory()
{
    var report = new System.Text.StringBuilder();

    decimal balance = 0;
    report.AppendLine("Date\t\tAmount\tBalance\tNote");
    foreach (var item in _allTransactions)
    {
        balance += item.Amount;
        report.AppendLine($"{item.Date.ToShortDateString()}\t{item.Amount}\t{balance}\t{item.Notes}");
    }

    return report.ToString();
}

Geçmiş, her işlem için bir satır içeren bir dizeyi biçimlendirmek için sınıfını kullanır StringBuilder . Bu öğreticilerin önceki bölümlerinde dize biçimlendirme kodunu gördünüz. Yeni bir karakter: \t. Bu, çıkışı biçimlendirmek için bir sekme ekler.

Program.cs'de test etmek için bu satırı ekleyin:

Console.WriteLine(account.GetAccountHistory());

Sonuçları görmek için programınızı çalıştırın.

Sonraki adımlar

Takıldıysanız GitHub depomuzda bu öğreticinin kaynağını görebilirsiniz.

Nesne odaklı programlama öğreticisiyle devam edebilirsiniz.

Bu kavramlar hakkında daha fazla bilgiyi şu makalelerde bulabilirsiniz: