Aracılığıyla paylaş


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

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

Önkoşullar

Yükleme yönergeleri

Windows'da tüm önkoşulları yüklemek için bu WinGet yapılandırma dosyası kullanılır. Zaten yüklü bir şey varsa WinGet bu adımı atlar.

  1. Dosyayı indirin ve çift tıklayarak çalıştırın.
  2. Lisans sözleşmesini okuyun, yyazın ve kabul etmek isteyip istemediğiniz sorulduğunda Enter seçin.
  3. Görev Çubuğunuzda yanıp sönen bir Kullanıcı Hesabı Denetimi (UAC) istemi alırsanız yüklemenin devam etmesi için izin verin.

Diğer platformlarda, bu bileşenlerin her birini ayrı ayrı yüklemeniz gerekir.

  1. Önerilen yükleyiciyi .NET SDK indirme sayfasından indirin ve çift tıklayarak çalıştırın. İndirme sayfası platformunuzu algılar ve platformunuz için en son yükleyiciyi önerir.
  2. Visual Studio Code giriş sayfasından en son yükleyiciyi indirin ve çift tıklayarak çalıştırın. Bu sayfa ayrıca platformunuzu algılar ve bağlantı sisteminiz için doğru olmalıdır.
  3. C# DevKit uzantısı sayfasındaki "Yükle" düğmesine tıklayın. Bu, Visual Studio code'u açar ve uzantıyı yüklemek mi yoksa etkinleştirmek mi istediğinizi sorar. "Yükle" seçeneğini belirleyin.

Uygulamanızı oluşturma

Terminal penceresi kullanarak Classes adlı bir dizin oluşturun. Uygulamanızı orada oluşturursunuz. 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 geri alınabilir.
  4. Depozitoları kabul ediyor.
  5. Para çekimine izin verir.
  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 eğitim nispeten küçüktür, bu nedenle tüm kodu tek bir ad alanına koyuyorsunuz.

public class BankAccount oluşturduğunuz sınıfı veya türü tanımlar. { 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 beş 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 için bu değerleri atayan bir oluşturucu tanımlamanız gerekir. Oluşturucu, sınıfın adıyla aynı adı taşıyan bir üyedir. Bu sınıf türüne ait nesneleri başlatmak için kullanılır. Aşağıdaki oluşturucuyu BankAccount türüne 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 yazabilirsiniz:

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.

Bir nesneyi new kullanarak oluşturduğunuzda, yapıcılar çağrılır. Program.csConsole.WriteLine("Hello World!");satırı 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.");

Şu ana kadar yaptığın şeyi çalıştıralım. Visual Studio kullanıyorsanız, Hata Ayıkla menüsünden Hata Ayıklamadan 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 ödevi 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, private, yalnızca BankAccount sınıfının 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 BankAccount nesnelerin bu değişkenin aynı tek örneğini paylaştığı 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_. s'nın static ve _'nın private alanını temsil etmesi. Her hesap numarasını başlatmak 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 eden yeni bir tür oluşturarak başlayın. İşlem, herhangi bir sorumlulukları olmayan bir record türdür. Birkaç özelliğe ihtiyacı var. Transaction.cs adlı yeni bir dosya oluşturun. Buna aşağıdaki kodu ekleyin:

namespace Classes;

public record Transaction(decimal Amount, DateTime Date, string Notes);

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

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

Şimdi Balance'yi doğru şekilde hesaplayalım. 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. Satır public decimal Balance { get; } içindeki BankAccount.cs'yi 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 listeler ve toplamı mevcut bakiye olarak sunar.

Ardından MakeDeposit ve MakeWithdrawal yöntemlerini uygulayın. Bu yöntemler son iki kuralı zorunlu tutar: ilk bakiye pozitif olmalı ve herhangi bir para ç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 tamamlayamaması durumunu belirtmenin standart yolu bir istisna 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);
}

throw deyimibir istisna fırlatır. Geçerli bloğun yürütülmesi sona erer ve kontrol, çağrı yığınında bulunan ilk eşleşen catch bloğuna aktarılır. Bu kodu biraz sonra test etmek için bir catch blok eklersiniz.

Oluşturucu, bakiyeyi doğrudan güncelleştirmek yerine ilk işlemi ekleyebilmesi için bir değişiklik almalıdır. MakeDeposit yöntemini zaten yazdığınız için, oluşturucunuzdan çağırın. Tamamlanmış oluşturucu aşağıdaki gibi 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 Main oluşturacak kodun ardından, BankAccount yönteminize 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;
}

Bir kod bloğunu işaretlemek ve beklediğiniz hataları yakalamak için cümlesini try-catch kullanırsınız. Negatif bakiye için özel durum oluşturan kodu test etmek için aynı tekniği kullanabilirsiniz. Yönteminizde invalidAccount içinde Main bildiriminin öncesine 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 .

Görev - tüm işlemleri günlüğe kaydetme

Bu öğreticiyi tamamlamak için, işlem geçmişi için bir GetAccountHistory oluşturan string yöntemini 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();
}

Tarihçe, her işlem için bir satır içeren bir dizeyi biçimlendirmek amacıyla StringBuilder sınıfını kullanır. Bu eğitimlerin önceki bölümlerinde dize biçimlendirmesini kullandı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());

Programınızı çalıştırın ve sonuçları denetleyin.

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: