Bagikan melalui


Menjelajahi pemrograman berorientasi objek dengan kelas dan objek

Dalam tutorial ini, Anda akan membangun aplikasi konsol dan melihat fitur dasar berorientasi objek yang merupakan bagian dari bahasa C#.

Prasyarat

Membuat aplikasi

Menggunakan jendela terminal, buat direktori bernama Kelas. Anda akan membuat aplikasi di sana. Ubah ke direktori tersebut dan ketik dotnet new console di jendela konsol. Perintah ini membuat aplikasi Anda. Buka Program.cs. Harusnya akan terlihat seperti ini:

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

Dalam tutorial ini, Anda akan membuat jenis baru yang mewakili rekening bank. Biasanya pengembang menentukan setiap kelas dalam file teks yang berbeda. Itu membuatnya lebih mudah dikelola saat ukuran program bertambah. Buat file baru bernama BankAccount.cs di direktori Kelas.

File ini akan berisi definisi rekening bank. Pemrograman Berorientasi Objek mengatur kode dengan membuat jenis dalam bentuk kelas. Kelas-kelas ini berisi kode yang mewakili entitas tertentu. Kelas BankAccount mewakili rekening bank. Kode mengimplementasikan operasi tertentu melalui metode dan properti. Dalam tutorial ini, rekening bank mendukung perilaku ini:

  1. Ini memiliki angka 10 digit yang secara unik mengidentifikasi rekening bank.
  2. Ini memiliki string yang menyimpan nama atau nama pemilik.
  3. Saldo dapat diambil.
  4. Ini menerima deposit.
  5. Ini menerima penarikan.
  6. Saldo awal harus positif.
  7. Penarikan tidak dapat mengakibatkan saldo negatif.

Tentukan jenis rekening bank

Anda dapat memulai dengan membuat dasar-dasar kelas yang menentukan perilaku tersebut. Buat file baru menggunakan perintah File:New. Beri nama BankAccount.cs. Tambahkan kode berikut ke file BankAccount.cs Anda:

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)
    {
    }
}

Sebelum melanjutkan, mari kita lihat apa yang telah Anda bangun. Deklarasi namespace ini menyediakan cara untuk mengatur kode Anda secara logis. Tutorial ini relatif kecil, jadi Anda akan menempatkan semua kode dalam satu namespace.

public class BankAccount menentukan kelas, atau jenis, yang Anda buat. Segala sesuatu di { dalam dan } yang mengikuti deklarasi kelas mendefinisikan status dan perilaku kelas. Ada lima anggota kelas BankAccount. Tiga pertama adalah properti . Properti adalah elemen data dan dapat memiliki kode yang memberlakukan validasi atau aturan lainnya. Dua yang terakhir adalah metode. Metode adalah blok kode yang melakukan satu fungsi. Membaca nama masing-masing anggota harus memberikan informasi yang cukup bagi Anda atau pengembang lain untuk memahami apa yang dilakukan kelas.

Buka rekening baru

Fitur pertama yang diterapkan adalah membuka rekening bank. Saat pelanggan membuka rekening, mereka harus menyediakan saldo awal, dan informasi tentang pemilik atau pemilik rekening tersebut.

Membuat objek baru dari jenis berarti BankAccount menentukan konstruktor yang menetapkan nilai-nilai tersebut. Konstruktor adalah anggota yang memiliki nama yang sama dengan kelas. Ini digunakan untuk menginisialisasi objek dari jenis kelas tersebut. Tambahkan konstruktor berikut ke jenis BankAccount: Tambahkan kode berikut di atas deklarasi kelas MakeDeposit:

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

Kode sebelumnya mengidentifikasi properti objek yang sedang dibangun dengan menyertakan kualifikasi this. Kualifikasi tersebut biasanya opsional dan dihilangkan. Anda juga bisa menulis:

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

Kualifikasi this hanya diperlukan saat variabel atau parameter lokal memiliki nama yang sama dengan bidang atau properti tersebut. Kualifikasi this dihilangkan di seluruh sisa artikel ini kecuali diperlukan.

Konstruktor dipanggil saat Anda membuat objek menggunakan new. Ganti baris Console.WriteLine("Hello World!"); di Program.cs dengan kode berikut (ganti <name> dengan nama Anda):

using Classes;

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

Mari kita jalankan apa yang telah Anda bangun sejauh ini. Jika Anda menggunakan Visual Studio, Pilih Mulai tanpa penelusuran kesalahan dari menu Debug. Jika Anda menggunakan baris perintah, ketik dotnet run direktori tempat Anda membuat proyek.

Apakah Anda melihat bahwa nomor rekening kosong? Sudah waktunya untuk memperbaikinya. Nomor rekening harus ditetapkan saat objek dibangun. Tetapi seharusnya tidak menjadi tanggung jawab pemanggil untuk membuatnya. Kode kelas BankAccount harus tahu cara menetapkan nomor rekening baru. Cara sederhana adalah memulai dengan angka 10 digit. Tingkatkan saat setiap rekening baru dibuat. Terakhir, simpan nomor rekening saat ini saat objek dibuat.

Tambahkan deklarasi anggota ke kelas BankAccount. Tempatkan baris kode berikut setelah kurung kurawal buka { di awal kelas BankAccount:

private static int s_accountNumberSeed = 1234567890;

accountNumberSeed adalah anggota data. Ini private, yang berarti hanya dapat diakses oleh kode dalam kelas BankAccount. Ini adalah cara untuk memisahkan tanggung jawab publik (seperti memiliki nomor rekening) dari implementasi privat (bagaimana nomor rekening dihasilkan). Ini juga static, yang berarti dibagikan oleh semua objek BankAccount. Nilai variabel non-statis unik untuk setiap instans objek BankAccount. accountNumberSeed adalah private static bidang dan dengan demikian memiliki awalan s_ sesuai konvensi penamaan C#. Bidang s penolakan static dan _ penolakan private . Tambahkan dua baris berikut ke konstruktor untuk menetapkan nomor rekening. Tempatkan setelah baris yang mengatakan this.Balance = initialBalance:

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

Ketik dotnet run untuk melihat hasilnya.

Membuat deposit dan penarikan

Kelas rekening bank Anda perlu menerima deposit dan penarikan agar berfungsi dengan benar. Mari kita terapkan setoran dan penarikan dengan membuat jurnal setiap transaksi untuk akun. Melacak setiap transaksi memiliki beberapa keuntungan daripada hanya memperbarui saldo pada setiap transaksi. Riwayat dapat digunakan untuk mengaudit semua transaksi dan mengelola saldo harian. Menghitung saldo dari riwayat semua transaksi saat diperlukan memastikan kesalahan apa pun dalam satu transaksi yang diperbaiki akan tercermin dengan benar dalam saldo pada komputasi berikutnya.

Mari kita mulai dengan membuat jenis baru untuk mewakili transaksi. Transaksi adalah jenis sederhana yang tidak memiliki tanggung jawab apa pun. Ini membutuhkan beberapa properti. Buat file baru bernama Transaction.cs. Tambahkan kode berikut:

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;
    }
}

Sekarang, mari kita tambahkan objek List<T> dari Transaction ke kelas BankAccount. Tambahkan deklarasi berikut setelah konstruktor dalam file BankAccount.cs Anda:

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

Sekarang, mari kita komputasi Balancedengan benar. Saldo saat ini dapat ditemukan dengan menjumlahkan nilai semua transaksi. Karena kode saat ini, Anda hanya bisa mendapatkan saldo awal rekening, jadi Anda harus memperbarui properti Balance Ganti baris public decimal Balance { get; } di BankAccount.cs dengan kode berikut:

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

        return balance;
    }
}

Contoh ini menunjukkan aspek penting dari properti. Anda sekarang menghitung saldo saat programmer lain meminta nilainya. Komputasi Anda menghitung semua transaksi, dan menyediakan jumlah sebagai saldo saat ini.

Selanjutnya, terapkan metode MakeDeposit dan MakeWithdrawal. Metode ini akan memberlakukan dua aturan akhir: saldo awal harus positif, dan penarikan apa pun tidak boleh menciptakan saldo negatif.

Aturan ini memperkenalkan konsep pengecualian. Cara standar untuk menunjukkan bahwa metode tidak dapat menyelesaikan pekerjaannya dengan sukses adalah dengan melemparkan pengecualian. Jenis pengecualian dan pesan yang terkait dengannya menjelaskan kesalahan. Di sini, MakeDeposit metode ini memberikan pengecualian jika jumlah deposit tidak lebih besar dari 0. Metode ini MakeWithdrawal memberikan pengecualian jika jumlah penarikan tidak lebih besar dari 0, atau jika menerapkan hasil penarikan dalam saldo negatif. Tambahkan kode berikut setelah deklarasi _allTransactions daftar:

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);
}

Pernyataan tersebut throw melemparkan pengecualian. Eksekusi blok saat ini berakhir, dan kontrol transfer ke blok pencocokan catch pertama yang ditemukan di tumpukan panggilan. Anda akan menambahkan catch blok untuk menguji kode ini nanti.

Konstruktor harus mendapatkan satu perubahan sehingga menambahkan transaksi awal, daripada memperbarui saldo secara langsung. Karena Anda sudah menulis metode MakeDeposit, panggil dari konstruktor Anda. Konstruktor yang sudah selesai akan terlihat seperti ini:

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

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

DateTime.Now adalah properti yang mengembalikan tanggal dan waktu saat ini. Uji kode ini dengan menambahkan beberapa deposit dan penarikan dalam metode Anda Main, mengikuti kode yang membuat BankAccount baru:

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

Selanjutnya, uji bahwa Anda menangkap kondisi kesalahan dengan mencoba membuat akun dengan saldo negatif. Di bawah kode yang baru saja Anda masukkan, tambahkan kode berikut:

// 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;
}

Anda menggunakan try-catch pernyataan untuk menandai blok kode yang dapat melempar pengecualian dan untuk menangkap kesalahan yang Anda harapkan. Anda dapat menggunakan teknik yang sama untuk menguji kode yang melempar pengecualian untuk keseimbangan negatif. Tambahkan kode berikut sebelum deklarasi invalidAccount dalam metode Anda Main:

// 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());
}

Simpan file, dan ketik dotnet run untuk mencobanya.

Tantangan - catat semua transaksi

Untuk menyelesaikan tutorial ini, Anda dapat menulis metode GetAccountHistory yang membuat string untuk riwayat transaksi. Tambahkan metode ini ke jenis BankAccount:

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();
}

Riwayat menggunakan kelas StringBuilder untuk memformat string yang berisi satu baris untuk setiap transaksi. Anda telah melihat kode pemformatan string sebelumnya dalam tutorial ini. Satu karakter baru adalah \t. Yang menyisipkan tab untuk memformat output.

Tambahkan baris ini untuk mengujinya di Program.cs:

Console.WriteLine(account.GetAccountHistory());

Jalankan program Anda untuk melihat hasilnya.

Langkah berikutnya

Jika Anda kebingungan, Anda dapat melihat sumber untuk tutorial ini di repositori GitHub kami.

Anda dapat melanjutkan dengan tutorial pemrograman berorientasi objek.

Anda dapat mempelajari selengkapnya tentang konsep-konsep tersebut di artikel ini: