สํารวจโพลีมอฟิฟิสที่ใช้สืบทอดกัน

เสร็จสมบูรณ์เมื่อ

โพลีมอฟิฟิกที่ใช้การสืบทอดนั้นยึดตามลําดับชั้นของคลาสที่คลาสสืบทอดลักษณะการทํางานและคุณสมบัติจากคลาสพื้นฐาน ความสัมพันธ์แบบสืบทอดจะช่วยให้คุณสามารถจัดการกับออบเจ็กต์ของคลาสที่ได้รับมาเป็นออบเจ็กต์ของคลาสพื้นฐาน การที่ถือว่าออบเจ็กต์คลาสที่ได้รับมาเป็นออบเจ็กต์คลาสพื้นฐานช่วยให้คุณสามารถเขียนโค้ดที่ทํางานกับออบเจ็กต์หลายชนิดโดยไม่ทราบชนิดเฉพาะในเวลาที่คอมไพล์

ตัวอย่างโค้ดต่อไปนี้แสดงให้เห็นถึงโพลีมอฟิฟิกแบบอิงตามการสืบทอดใน 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();
        }
    }
}

ในโค้ดตัวอย่างนี้ โปรดสังเกตว่าคลาส Program จะสร้างอาร์เรย์ของออบเจ็กต์ Animal และกําหนดอินสแตนซ์ของ DogCatและ Cow ไปยังองค์ประกอบอาร์เรย์ มีการเรียกใช้เมธอด MakeSound บนแต่ละวัตถุในอาร์เรย์ โดยแสดงโพลีมอฟิฟิก วิธีการ MakeSound ถูกแทนที่ในชั้นเรียนที่ได้รับมาเพื่อให้พฤติกรรมที่เฉพาะเจาะจงสําหรับสัตว์แต่ละชนิด

แปลงออบเจ็กต์ของคลาสฐานเป็นคลาสที่ได้รับมา

การคัดเลือกใน C# คือกระบวนการในการแปลงวัตถุชนิดหนึ่งเป็นอีกชนิดหนึ่ง การคัดเลือกมักจะใช้เมื่อใช้งานพอลิมอฟิกโดยใช้ลําดับชั้นการสืบทอดซึ่งคุณมีระดับชั้นฐานและคลาสที่สืบทอดมาอย่างน้อยหนึ่งประเภท

การหล่อมีสองประเภทหลัก:

  • การคัดเลือกโดยนัย: จะเกิดขึ้นโดยอัตโนมัติเมื่อแปลงคลาสที่ได้รับมาเป็นคลาสพื้นฐาน ซึ่งจะปลอดภัยเนื่องจากทุกอินสแตนซ์ของคลาสที่ได้รับมานั้นเป็นอินสแตนซ์ของคลาสพื้นฐานด้วย

    
    BankAccount account = new CheckingAccount();
    
    
  • การคัดเลือกแบบชัดเจน: ต้องใช้ตัวดําเนินการ Cast และใช้เมื่อแปลงคลาสฐานเป็นคลาสที่ได้รับมา ซึ่งไม่ปลอดภัยเสมอไปเนื่องจากไม่ใช่ทุกอินสแตนซ์ของคลาสฐานคืออินสแตนซ์ของคลาสที่ได้รับมา

    
    CheckingAccount checkingAccount = (CheckingAccount)account;
    
    

แปลงวัตถุโดยใช้คําสําคัญ is และ as

ใน C# คุณสามารถแคสต์ออบเจ็กต์โดยใช้คํา is สําคัญ และ as ได้ คําหลักเหล่านี้เป็นวิธีที่ปลอดภัยในการตรวจสอบชนิดของวัตถุก่อนที่จะแคสต์ไปยังประเภทอื่น ต่อไปนี้เป็นวิธีทั่วไปในการส่งออบเจ็กต์ใน C#:

  • ใช้คําสําคัญ is ที่มีการจับคู่รูปแบบ:

    
    if (account is CheckingAccount checkingAccount)
    {
        // Use checkingAccount as a CheckingAccount
    }
    
    
    • ไวยากรณ์นี้จะตรวจสอบว่า account เป็นชนิด CheckingAccountหรือไม่
    • หากการตรวจสอบเสร็จสมบูรณ์ ระบบจะแปลง account เป็น CheckingAccount และกําหนดให้กับตัวแปร checkingAccount
    • วิธีการนี้เป็นไปอย่างรัดกุมและปลอดภัยเนื่องจากเป็นการผสมผสานการตรวจสอบชนิดและการส่งในขั้นตอนเดียว
  • การใช้คําสําคัญ is ตามด้วย casting อย่างชัดเจน:

    
    if (account is CheckingAccount)
    {
        CheckingAccount checkingAccount = (CheckingAccount)account;
        // Use checkingAccount as a CheckingAccount
    }
    
    
    • ไวยากรณ์นี้จะตรวจสอบว่า account เป็นชนิด CheckingAccountหรือไม่
    • หากการตรวจสอบเสร็จสมบูรณ์ ระบบจะแปลง account เป็น CheckingAccount และกําหนดให้กับตัวแปร checkingAccount
    • วิธีการนี้เป็นแบบอย่างละเอียดมากกว่าไวยากรณ์การจับคู่รูปแบบ แต่ให้การควบคุมกระบวนการคัดเลือกได้มากขึ้น
  • การใช้คําสําคัญ as:

    
    CheckingAccount checkingAccount = account as CheckingAccount;
    
    if (checkingAccount != null)
    {
        // Use checkingAccount as a CheckingAccount
    }
    
    
    • ไวยากรณ์นี้จะพยายามส่ง account ไปยัง CheckingAccount และกําหนดผลลัพธ์เป็น checkingAccount
    • หากแคสต์สําเร็จ checkingAccount ประกอบด้วยวัตถุหล่อ มิฉะนั้นจะเป็น null
    • วิธีการนี้มีประโยชน์เมื่อคุณต้องการตรวจสอบผลลัพธ์ Cast ก่อนที่จะใช้วัตถุ cast ตัวอย่างเช่น เมื่อคุณต้องการหลีกเลี่ยงข้อยกเว้นและจัดการกรณีความล้มเหลวอย่างนุ่มนวล
  • เมื่อนําการคัดเลือกไปใช้ ให้พิจารณาแนวทางต่อไปนี้:

    • ใช้การจับคู่รูปแบบกับ is: รวมการตรวจสอบประเภทและส่งในขั้นตอนเดียว
    • การใช้คําหลัก is ที่มี cast อย่างชัดเจน: แยกประเภทการตรวจสอบและแปลงเป็นสองขั้นตอนเพื่อให้สามารถควบคุมกระบวนการหล่อได้มากขึ้น
    • การใช้คําสําคัญ as: พยายามแปลงและจัดการความล้มเหลวอย่างนุ่มนวลโดยส่งคืนค่า null

การทําความเข้าใจเทคนิคการคัดเลือกเหล่านี้เป็นสิ่งสําคัญสําหรับการทํางานกับพอลิมอฟิสและการรับทอดใน C#

หลีกเลี่ยงข้อผิดพลาดทั่วไปเมื่อใช้งาน polymorphism

เมื่อเป้าหมายของคุณคือโพลีมอฟิสต์ที่ยึดตามการสืบทอดนี่คือสิ่งที่ต้องหลีกเลี่ยงและบางสิ่งที่ต้องทําให้แน่ใจว่า:

  • หลีกเลี่ยงการใช้คลาสและวิธีการที่ปิดผนึก: คลาสและวิธีการที่ปิดผนึกไม่สามารถสืบทอดหรือแทนที่ได้ซึ่ง จํากัด ความสามารถในการใช้พอลิมอฟิสติก ถ้าคุณปิดผนึกคลาสหรือเมธอด คุณจะป้องกันไม่ให้ส่วนขยายและการปรับแต่งเพิ่มเติม เช่น:

    
    public sealed class BankAccount { } // This class can't be inherited
    
    
  • หลีกเลี่ยงการใช้วิธีการแบบคงที่มากเกินไป วิธีการแบบคงที่เป็นสมาชิกของคลาสแทนที่จะเป็นอินสแตนซ์ของคลาส พวกเขาไม่สามารถถูกแทนที่ซึ่งหมายความว่าพวกเขาไม่ได้มีส่วนร่วมในพอลิมอฟิส

    
    public static void PrintMessage() { } // This method can't be overridden
    
    
  • หลีกเลี่ยงการมีเพศสัมพันธ์แน่น การมีเพศสัมพันธ์หนาแน่นเกิดขึ้นเมื่อคลาสหรือส่วนประกอบในระบบขึ้นอยู่กับกันและกันเป็นอย่างมาก ซึ่งหมายความว่าการเปลี่ยนแปลงในคลาสหนึ่งสามารถส่งผลโดยตรงต่อชั้นเรียนอื่น ทําให้ระบบมีความยืดหยุ่นและยากขึ้นในการบํารุงรักษา การมีเพศสัมพันธ์ที่หนาแน่นอาจนําไปสู่ปัญหาในการทดสอบ ขยาย และปรับเปลี่ยนโค้ด

    
    public class BankAccount
    {
        public void TransferFunds(SavingsAccount savingsAccount)
        {
            // Tight coupling with SavingsAccount
        }
    }
    
    
  • หลีกเลี่ยงการใช้คําหลัก 'ใหม่' โดยไม่มีเหตุผลที่ดี คําหลัก 'ใหม่' จะซ่อนเมธอดระดับฐานในคลาสที่ได้รับซึ่งอาจทําให้เกิดความสับสนและลักษณะการทํางานที่ไม่คาดคิด ใช้คําสําคัญ 'ใหม่' เมื่อคุณต้องการซ่อนเมธอดคลาสพื้นฐานโดยตั้งใจเท่านั้น

    
    public class Dog : Animal
    {
        public new void MakeSound() // Hides the base class method. Better to use 'override'
        {
            Console.WriteLine("The dog barks.");
        }
    }
    
    
  • ตรวจสอบให้แน่ใจว่าลายเซ็นของเมธอดสอดคล้องกัน ตรวจสอบให้แน่ใจว่าวิธีการแทนที่ในคลาสที่ได้รับมามีลายเซ็นเดียวกันกับวิธีการคลาสพื้นฐาน การเปลี่ยนลายเซ็นของเมธอด จะทําให้วิธีการซ่อนแทนที่จะแทนที่

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

สรุป

โพลีมอฟิฟิกที่ใช้การสืบทอดใน C# ช่วยให้คุณสามารถสร้างลําดับชั้นของคลาสที่สืบทอดลักษณะการทํางานและคุณสมบัติจากคลาสพื้นฐานได้ กลไกการสืบทอดนี้จะช่วยให้คุณสามารถจัดการกับออบเจ็กต์ของคลาสที่ได้รับมาเป็นออบเจ็กต์ของคลาสพื้นฐาน ความสามารถในการปฏิบัติต่อออบเจ็กต์คลาสที่ได้รับมาเป็นสมาชิกของคลาสพื้นฐานช่วยให้คุณสามารถเขียนโค้ดที่ทํางานกับออบเจ็กต์หลายชนิดโดยไม่ทราบชนิดเฉพาะในเวลาที่คอมไพล์ โดยการทําความเข้าใจเทคนิคการคัดเลือกเพื่อหลีกเลี่ยงข้อผิดพลาดทั่วไปและทําตามแนวทางปฏิบัติที่ดีที่สุดคุณสามารถใช้โพลิมอฟิกในแอปพลิเคชัน C# ของคุณได้อย่างมีประสิทธิภาพ