Menjelajahi polimorfisme berbasis warisan
Polimorfisme berbasis warisan didasarkan pada hierarki kelas di mana kelas turunan mewarisi perilaku dan properti dari kelas dasar. Hubungan warisan memungkinkan Anda memperlakukan objek kelas turunan sebagai objek kelas dasar. Mampu memperlakukan objek kelas turunan sebagai objek kelas dasar memungkinkan Anda menulis kode yang berfungsi dengan beberapa jenis objek tanpa mengetahui jenis tertentu pada waktu kompilasi.
Sampel kode berikut menunjukkan polimorfisme berbasis warisan dalam C#:
// Base class
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("The animal makes a sound.");
}
}
// Derived class Dog
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("The dog barks.");
}
}
// Derived class Cat
public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("The cat meows.");
}
}
// Derived class Cow
public class Cow : Animal
{
public override void MakeSound()
{
Console.WriteLine("The cow moos.");
}
}
class Program
{
static void Main()
{
// Create an array of Animal objects
Animal[] animals = new Animal[3];
Animal animal1 = new Dog();
Animal animal2 = new Cat();
Animal animal3 = new Cow();
animals[0] = animal1;
animals[1] = animal2;
animals[2] = animal3;
// Demonstrate polymorphism
foreach (Animal animal in animals)
{
animal.MakeSound();
}
}
}
Dalam kode sampel ini, perhatikan bahwa kelas Program membuat array objek Animal dan menetapkan instans Dog, Cat, dan Cow ke elemen array. Metode MakeSound dipanggil pada setiap objek dalam array, menunjukkan polimorfisme. Metode MakeSound dioverride dalam kelas turunan untuk memberikan perilaku khusus pada setiap tipe hewan.
Melemparkan objek kelas dasar ke kelas turunan
Casting di C# adalah proses mengonversi objek dari satu jenis ke jenis lain. Casting sering digunakan saat menerapkan polimorfisme menggunakan hierarki warisan, di mana Anda memiliki kelas dasar dan satu atau beberapa kelas turunan.
Ada dua jenis pengecoran utama:
Casting Implisit: Ini terjadi secara otomatis saat mengonversi kelas turunan ke kelas dasar. Ini aman karena setiap instans kelas turunan juga merupakan instans kelas dasar.
BankAccount account = new CheckingAccount();Casting Eksplisit: Ini memerlukan penggunaan operator casting dan digunakan ketika mengonversi kelas dasar menjadi kelas turunan. Ini tidak selalu aman karena tidak setiap instans kelas dasar adalah instans kelas turunan.
CheckingAccount checkingAccount = (CheckingAccount)account;
Ubah objek dengan menggunakan kata kunci is dan as
Di C#, Anda dapat melemparkan objek menggunakan is kata kunci dan as . Kata kunci ini menyediakan cara yang aman untuk memeriksa jenis objek sebelum mentransmisiannya ke jenis lain. Berikut adalah beberapa cara umum untuk melemparkan objek di C#:
Menggunakan kata kunci
isdengan pencocokan pola:if (account is CheckingAccount checkingAccount) { // Use checkingAccount as a CheckingAccount }- Sintaks ini memeriksa apakah
accountberjenisCheckingAccount. - Jika pemeriksaan berhasil,
accountakan di-cast keCheckingAccountdan diberikan ke variabelcheckingAccount. - Pendekatan ini ringkas dan aman, karena memadukan pemeriksaan tipe dan pengubahan tipe dalam satu langkah.
- Sintaks ini memeriksa apakah
Menggunakan kata kunci
isdiikuti dengan pemeran eksplisit.if (account is CheckingAccount) { CheckingAccount checkingAccount = (CheckingAccount)account; // Use checkingAccount as a CheckingAccount }- Sintaks ini memeriksa apakah
accountberjenisCheckingAccount. - Jika pemeriksaan berhasil, secara eksplisit melemparkan
accountkeCheckingAccountdan menetapkannya ke variabelcheckingAccount. - Pendekatan ini lebih banyak dijelaskan daripada sintaks pencocokan pola, tetapi memberikan kontrol lebih besar atas proses pembentukan tipe.
- Sintaks ini memeriksa apakah
Menggunakan kata kunci
as:CheckingAccount checkingAccount = account as CheckingAccount; if (checkingAccount != null) { // Use checkingAccount as a CheckingAccount }- Sintaks ini mencoba untuk mentransmisikan
accountkeCheckingAccountdan menetapkan hasilnya kecheckingAccount. - Jika pelemparan berhasil,
checkingAccountberisi objek pelemparan; jika tidak, nilainya null. - Pendekatan ini berguna ketika Anda ingin memeriksa hasil cast sebelum menggunakan objek cast. Misalnya, ketika Anda ingin menghindari pengecualian dan menangani kasus kegagalan dengan anggun.
- Sintaks ini mencoba untuk mentransmisikan
Saat menerapkan penuangan, pertimbangkan panduan berikut:
- Menggunakan pencocokan pola dengan
is: Menggabungkan pemeriksaan jenis dan casting dalam satu langkah. - Menggunakan kata kunci
isdengan penerapan eksplisit: Memisahkan pemeriksaan jenis dan menguraikan menjadi dua langkah, memberikan kontrol lebih besar atas proses casting. - Menggunakan kata kunci
as: Mencoba pengubahan tipe dan menangani kegagalan dengan baik dengan mengembalikan null.
- Menggunakan pencocokan pola dengan
Memahami teknik pengecoran ini sangat penting untuk bekerja dengan polimorfisme dan warisan dalam C#.
Hindari jebakan umum saat menerapkan polimorfisme
Ketika tujuan Anda adalah polimorfisme berbasis warisan, berikut adalah beberapa hal yang harus dihindari dan beberapa hal untuk memastikan:
Hindari menggunakan kelas dan metode yang disegel: Kelas dan metode yang disegel tidak dapat diwariskan atau ditimpa, yang membatasi kemampuan untuk menggunakan polimorfisme. Jika Anda menutup kelas atau metode, Anda mencegah ekstensi dan kustomisasi lebih lanjut. Misalnya:
public sealed class BankAccount { } // This class can't be inheritedHindari menggunakan metode statis secara berlebihan. Metode statis adalah milik sebuah kelas dan bukan milik suatu objek dari kelas tersebut. Mereka tidak dapat ditimpa, yang berarti mereka tidak mengambil bagian dalam polimorfisme.
public static void PrintMessage() { } // This method can't be overriddenHindari kopling yang ketat. Kopling yang ketat terjadi ketika kelas atau komponen dalam sistem sangat bergantung satu sama lain. Ini berarti bahwa perubahan dalam satu kelas dapat secara langsung memengaruhi kelas lain, membuat sistem kurang fleksibel dan lebih sulit dipertahankan. Kopling yang ketat dapat menyebabkan kesulitan dalam pengujian, perluasan, dan modifikasi kode.
public class BankAccount { public void TransferFunds(SavingsAccount savingsAccount) { // Tight coupling with SavingsAccount } }Hindari menggunakan kata kunci 'baru' tanpa alasan yang baik. Kata kunci 'baru' menyembunyikan metode kelas dasar di kelas turunan, yang dapat menyebabkan kebingungan dan perilaku yang tidak terduga. Hanya gunakan kata kunci 'baru' ketika Anda ingin menyembunyikan metode kelas dasar dengan sengaja.
public class Dog : Animal { public new void MakeSound() // Hides the base class method. Better to use 'override' { Console.WriteLine("The dog barks."); } }Pastikan tanda tangan metode yang konsisten. Pastikan bahwa metode yang ditimpa dalam kelas turunan memiliki spesifikasi yang sama dengan metode di kelas dasar. Mengubah penandatanganan metode akan mengakibatkan metode disembunyikan daripada mengoverride.
public class Animal { public virtual void MakeSound(string sound) { Console.WriteLine("The animal makes a sound."); } } public class Dog : Animal { // Method signature doesn't match the base class public override void MakeSound() { Console.WriteLine("The dog barks."); } }
Ringkasan
Polimorfisme berbasis warisan dalam C# memungkinkan Anda membuat hierarki kelas di mana kelas turunan mewarisi perilaku dan properti dari kelas dasar. Mekanisme pewarisan ini memungkinkan Anda memperlakukan objek kelas turunan sebagai objek kelas dasar. Kemampuan untuk memperlakukan objek kelas turunan sebagai anggota kelas dasar memungkinkan Anda menulis kode yang berfungsi dengan beberapa jenis objek tanpa mengetahui jenis tertentu pada waktu kompilasi. Dengan memahami teknik pengecoran, menghindari jebakan umum, dan mengikuti praktik terbaik, Anda dapat secara efektif menerapkan polimorfisme dalam aplikasi C# Anda.