C# - C Sharp: Ghi đè phương thức (Overriding) với new
C# cho phép lớp con có quyền tạo một phương thức giống hệt với phương thức của lớp cha. Điều này gọi là Ghi đè phương thức (Override). Việc ghi đè này cho phép một lớp thừa kế hành vi từ một lớp khác nhưng có thể thay đổi hành vi đó khi cần.
Một số quy tắc cần nhớ khi ghi đè:
- Phương thức ghi đè phải cùng tên, kiểu, và số lượng đối số cũng như kiểu trả về với phương thức của lớp cha.
- Một phương thức ghi đè không thể có mức truy cập yếu hơn so với mức truy cập của phương thức tương ứng ở lớp cha.
Ví dụ ta có lớp Animal2 như sau:
class Animal2 { int id; string? name; float weight; string? gender; public int Id { get => id; set => id = value; } public string? Name { get => name; set => name = value; } public float Weight { get => weight; set => weight = value; } public string? Gender { get => gender; set => gender = value; } public Animal2() { } public Animal2(int id, string name, float weight, string gender) { this.id = id; this.name = name; this.weight = weight; this.gender = gender; } public void InputInfo() { Console.WriteLine("\nInput information for cat:"); Console.Write("Input id: "); id = int.Parse(Console.ReadLine()); Console.Write("Input name: "); name = Console.ReadLine(); Console.Write("Input weight: "); weight = float.Parse(Console.ReadLine()); Console.Write("Input gender: "); gender = Console.ReadLine(); } public void ShowInfo() { Console.WriteLine("\nShow information of cat:"); Console.WriteLine($"Id: {id}"); Console.WriteLine($"Name: {name}"); Console.WriteLine($"Weight: {weight}"); Console.WriteLine($"Gender: {gender}"); } }
Trong lớp Animal2 có hai phương thức là InputInfo() dùng để nhập liệu cho các trường id, name, weight và gender; còn phương thức ShowInfo() dùng để hiển thị dữ liệu của các trường id, name, weight và age.
Và bây giờ ta có lớp Cat2 thừa kế lớp Animal2 ở trên như sau:
class Cat2 : Animal2 { string? color; public string? Color { get => color; set => color = value;} }
Thì đương nhiên lớp Cat2 sẽ được thừa hưởng các phương thức InputInfo() và ShowInfo() của lớp Animal2.
Tuy nhiên, phương thức InputInfo() của lớp cha Animal2 lại không thể nhập liệu cho trường color của lớp con Cat2, và phương thức ShowInfo() của lớp cha Animal2 cũng không thể hiển thị cho trường color của lớp con Cat2.
Để khắc phục thì ta tiến hành ghi đè hai phương thức này như sau:
class Cat2 : Animal2 { string? color; public string? Color { get => color; set => color = value;} //ghi đè phương thức InputInfo() của lớp cha sử dụng từ khóa new public new void InputInfo() { base.InputInfo(); Console.Write("Input color: "); color = Console.ReadLine(); } //ghi đè phương thức ShowInfo() của lớp cha sử dụng từ khóa new public new void ShowInfo() { base.ShowInfo(); Console.WriteLine($"Color: {color}"); } }
Ở đoạn code trên có sử dụng đến từ khóa base, bạn có thể tìm hiểu thêm về từ khóa base tại ĐÂY.
Còn dưới đây là đoạn code hoàn chỉnh, bạn có thể copy và chạy thử:
namespace ConsoleApp1 { class Animal2 { int id; string? name; float weight; string? gender; public int Id { get => id; set => id = value; } public string? Name { get => name; set => name = value; } public float Weight { get => weight; set => weight = value; } public string? Gender { get => gender; set => gender = value; } public Animal2() { } public Animal2(int id, string name, float weight, string gender) { this.id = id; this.name = name; this.weight = weight; this.gender = gender; } public void InputInfo() { Console.WriteLine("\nInput information for cat:"); Console.Write("Input id: "); id = int.Parse(Console.ReadLine()); Console.Write("Input name: "); name = Console.ReadLine(); Console.Write("Input weight: "); weight = float.Parse(Console.ReadLine()); Console.Write("Input gender: "); gender = Console.ReadLine(); } public void ShowInfo() { Console.WriteLine("\nShow information of cat:"); Console.WriteLine($"Id: {id}"); Console.WriteLine($"Name: {name}"); Console.WriteLine($"Weight: {weight}"); Console.WriteLine($"Gender: {gender}"); } } class Cat2 : Animal2 { string? color; public string? Color { get => color; set => color = value; } public new void InputInfo() { base.InputInfo(); Console.Write("Input color: "); color = Console.ReadLine(); } public new void ShowInfo() { base.ShowInfo(); Console.WriteLine($"Color: {color}"); } } internal class Demo { static void Main(string[] args) { Cat2 cat = new Cat2(); //truy cập các thuộc tính của cat được thừa hưởng từ Animal: cat.Id = 1234; cat.Name = "Moon"; cat.Weight = 1.5f; cat.Gender = "Female"; cat.Color = "Black"; //truy cập các phương thức của cat được thừa hường từ Animal: cat.ShowInfo();//hiển thị thông tin của cat cat.InputInfo();//nhập thông tin cho cat cat.ShowInfo();//hiển thị thông tin sau khi nhập (kiểm tra coi nhập được không) } } }
Kết quả:
Show information of cat: Id: 1234 Name: Moon Weight: 1.5 Gender: Female Color: Black Input information for cat: Input id: 5768 Input name: Sun Input weight: 3.7 Input gender: Male Input color: White Show information of cat: Id: 5768 Name: Sun Weight: 3.7 Gender: Male Color: White
Lưu ý: Các chú thích sẽ cung cấp thêm thông tin về chương trình. Các chú thích không ảnh hưởng đến chức năng của đoạn mã mà chúng chú thích.
Lưu ý rằng phương thức ShowInfo() bây giờ sẽ in ra thông tin cụ thể trong lớp con. Điều này có nghĩa rằng một lời gọi tới phương thức ShowInfo() sử dụng đối tượng lớp con là cat.ShowInfo() trước tiên sẽ tìm kiếm phương thức trong lớp con. Sau đó phương thức ShowInfo() được ghi đè trong lớp con, nó gọi phương thức ShowInfo() của lớp con mà không phải phương thức ShowInfo() của lớp cha. Phương thức InputInfo() cũng tương tự như vậy.