มีความแตกต่างระหว่างการเป็นnewและ/virtualoverride
คุณสามารถจินตนาการได้ว่าคลาสเมื่อยกตัวอย่างแล้วไม่มีอะไรมากไปกว่าโต๊ะพอยน์เตอร์ชี้ไปที่การใช้งานจริงของวิธีการ ภาพต่อไปนี้ควรแสดงให้เห็นภาพว่าค่อนข้างดี:

ขณะนี้มีหลายวิธีสามารถกำหนดวิธีการได้ แต่ละคนมีพฤติกรรมแตกต่างกันเมื่อใช้กับการสืบทอด วิธีมาตรฐานทำงานเหมือนภาพด้านบนเสมอ หากคุณต้องการเปลี่ยนพฤติกรรมนี้คุณสามารถแนบคำหลักที่แตกต่างกับวิธีการของคุณ
1. คลาสนามธรรม
abstractคนแรกคือ abstractวิธีการเพียงชี้ไปที่:

ถ้าคลาสของคุณมีสมาชิกแบบนามธรรมคลาสนั้นจำเป็นต้องถูกทำเครื่องหมายเป็นabstractมิฉะนั้นคอมไพเลอร์จะไม่คอมไพล์แอปพลิเคชันของคุณ คุณไม่สามารถสร้างอินสแตนซ์ของabstractคลาส แต่คุณสามารถสืบทอดจากคลาสเหล่านั้นและสร้างอินสแตนซ์ของคลาสที่สืบทอดของคุณและเข้าถึงคลาสโดยใช้การกำหนดคลาสพื้นฐาน ในตัวอย่างของคุณสิ่งนี้จะมีลักษณะดังนี้:
public abstract class Person
{
public abstract void ShowInfo();
}
public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a teacher!");
}
}
public class Student : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a student!");
}
}
หากเรียกว่าพฤติกรรมของShowInfoแตกต่างกันไปขึ้นอยู่กับการใช้งาน:
Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'
person = new Student();
person.ShowInfo(); // Shows 'I am a student!'
ทั้งStudents และTeachers เป็นPersonแต่พวกเขาทำงานแตกต่างกันเมื่อพวกเขาถูกขอให้พร้อมท์ข้อมูลเกี่ยวกับตัวเอง อย่างไรก็ตามวิธีการขอให้พวกเขาแจ้งข้อมูลเหมือนกัน: การใช้Personอินเทอร์เฟซสำหรับชั้นเรียน
ดังนั้นสิ่งที่เกิดขึ้นอยู่เบื้องหลังเมื่อคุณได้รับมรดกจากPerson? เมื่อใช้ShowInfoตัวชี้จะไม่ได้ชี้ไปที่ไหนใด ๆ อีกต่อไปได้ในขณะนี้ชี้ให้เห็นถึงการดำเนินงานที่เกิดขึ้นจริง! เมื่อสร้างStudentอินสแตนซ์มันจะชี้ไปStudentที่ShowInfo:

2. วิธีการเสมือนจริง
วิธีที่สองคือการใช้virtualวิธีการ ลักษณะการทำงานเหมือนกันยกเว้นคุณจะให้การใช้งานเริ่มต้นที่เป็นทางเลือกในคลาสพื้นฐานของคุณ คลาสที่มีvirtualสมาชิกสามารถถูกถอนการติดตั้งได้อย่างไรก็ตามคลาสที่สืบทอดมาสามารถจัดเตรียมการใช้งานที่แตกต่างกันได้ นี่คือสิ่งที่รหัสของคุณควรดูเหมือนทำงานจริง:
public class Person
{
public virtual void ShowInfo()
{
Console.WriteLine("I am a person!");
}
}
public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a teacher!");
}
}
แตกต่างที่สำคัญคือว่าสมาชิกฐานPerson.ShowInfoไม่ได้ชี้ไปที่ไหนใด ๆ อีกต่อไป นี่คือเหตุผลว่าทำไมคุณสามารถสร้างอินสแตนซ์ของPerson(และทำให้ไม่จำเป็นต้องทำเครื่องหมายเป็นabstractอีกต่อไป):

คุณควรสังเกตว่านี่ไม่ได้ดูแตกต่างจากภาพแรกในตอนนี้ นี่เป็นเพราะvirtualวิธีการชี้ไปที่การใช้งาน " วิธีมาตรฐาน " ใช้virtualคุณสามารถบอกได้Personsว่าพวกเขาสามารถ (ไม่ต้อง ) ShowInfoจัดให้มีการดำเนินงานที่แตกต่างกันสำหรับ ถ้าคุณให้การดำเนินงานที่แตกต่างกัน (ใช้override) เช่นผมสำหรับข้างต้นภาพจะมีลักษณะเช่นเดียวกับTeacher abstractลองนึกภาพเราไม่ได้ให้การปรับใช้ที่กำหนดเองสำหรับStudents:
public class Student : Person
{
}
รหัสจะถูกเรียกเช่นนี้:
Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'
person = new Student();
person.ShowInfo(); // Shows 'I am a person!'
และภาพStudentจะมีลักษณะเช่นนี้:

3. คำสำคัญ 'ใหม่' อาคาชื่อ "เงา"
newมีแฮ็คมากกว่านี้ คุณสามารถให้วิธีการในชั้นเรียนทั่วไปที่มีชื่อเดียวกันกับวิธีการในชั้นเรียน / อินเตอร์เฟซฐาน ทั้งสองชี้ไปที่การใช้งานที่กำหนดเอง:

การใช้งานมีลักษณะเหมือนที่คุณให้ไว้ พฤติกรรมนั้นแตกต่างกันไปตามวิธีการเข้าถึงวิธีการของคุณ:
Teacher teacher = new Teacher();
Person person = (Person)teacher;
teacher.ShowInfo(); // Prints 'I am a teacher!'
person.ShowInfo(); // Prints 'I am a person!'
พฤติกรรมนี้สามารถต้องการได้ แต่ในกรณีของคุณมันทำให้เข้าใจผิด
ฉันหวังว่านี่จะทำให้สิ่งต่าง ๆ ชัดเจนยิ่งขึ้นสำหรับคุณ!