Có sự khác biệt giữa new
và virtual
/ override
.
Bạn có thể tưởng tượng rằng một lớp, khi được khởi tạo, không gì khác hơn là một bảng con trỏ, chỉ ra việc thực hiện thực tế các phương thức của nó. Hình ảnh sau đây sẽ hình dung điều này khá tốt:
Bây giờ có nhiều cách khác nhau, một phương pháp có thể được xác định. Mỗi hành vi khác nhau khi nó được sử dụng với thừa kế. Cách tiêu chuẩn luôn hoạt động như hình ảnh trên minh họa. Nếu bạn muốn thay đổi hành vi này, bạn có thể đính kèm các từ khóa khác nhau vào phương pháp của mình.
1. Các lớp trừu tượng
Đầu tiên là abstract
. abstract
phương pháp chỉ đơn giản là trỏ đến hư không:
Nếu lớp của bạn chứa các thành viên trừu tượng, nó cũng cần được đánh dấu là abstract
, nếu không trình biên dịch sẽ không biên dịch ứng dụng của bạn. Bạn không thể tạo các thể hiện của abstract
các lớp, nhưng bạn có thể kế thừa từ chúng và tạo các thể hiện của các lớp được kế thừa của bạn và truy cập chúng bằng định nghĩa lớp cơ sở. Trong ví dụ của bạn, nó sẽ trông như sau:
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!");
}
}
Nếu được gọi, hành vi ShowInfo
khác nhau, dựa trên việc thực hiện:
Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'
person = new Student();
person.ShowInfo(); // Shows 'I am a student!'
Cả hai Student
và Teacher
s đều là Person
s, nhưng chúng cư xử khác nhau khi chúng được yêu cầu nhắc thông tin về bản thân. Tuy nhiên, cách để yêu cầu họ nhắc thông tin của họ là như nhau: Sử dụng Person
giao diện lớp.
Vì vậy, những gì xảy ra đằng sau hậu trường, khi bạn thừa hưởng từ Person
? Khi thực hiện ShowInfo
, con trỏ không còn trỏ đến đâu nữa, bây giờ nó trỏ đến việc thực hiện thực tế! Khi tạo một Student
thể hiện, nó trỏ đến Student
s ShowInfo
:
2. Phương thức ảo
Cách thứ hai là sử dụng virtual
các phương pháp. Hành vi là như nhau, ngoại trừ bạn đang cung cấp một triển khai mặc định tùy chọn trong lớp cơ sở của bạn. Các lớp với virtual
các thành viên có thể được cung cấp, tuy nhiên các lớp được kế thừa có thể cung cấp các triển khai khác nhau. Đây là những gì mã của bạn thực sự trông giống như để làm việc:
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!");
}
}
Sự khác biệt chính là, thành viên cơ sở Person.ShowInfo
không còn chỉ đến nơi nào nữa. Đây cũng là lý do, tại sao bạn có thể tạo các phiên bản của Person
(và do đó, nó không cần phải được đánh dấu là abstract
nữa):
Bạn nên chú ý rằng hình ảnh này không khác với hình ảnh đầu tiên bây giờ. Điều này là do virtual
phương thức này đang chỉ đến một cách thực hiện " cách tiêu chuẩn ". Sử dụng virtual
, bạn có thể nói Persons
rằng họ có thể (không phải ) cung cấp một triển khai khác cho ShowInfo
. Nếu bạn cung cấp một triển khai khác (sử dụng override
), giống như tôi đã làm Teacher
ở trên, hình ảnh sẽ trông giống như đối với abstract
. Hãy tưởng tượng, chúng tôi không cung cấp một triển khai tùy chỉnh cho Student
s:
public class Student : Person
{
}
Mã sẽ được gọi như thế này:
Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'
person = new Student();
person.ShowInfo(); // Shows 'I am a person!'
Và hình ảnh Student
sẽ như thế này:
3. Từ khóa `new` ma thuật hay còn gọi là" Shadowing "
new
nhiều hơn một hack xung quanh này. Bạn có thể cung cấp các phương thức trong các lớp tổng quát, có cùng tên với các phương thức trong lớp / giao diện cơ sở. Cả hai đều chỉ ra cách thực hiện tùy chỉnh của riêng họ:
Việc thực hiện trông giống như một, bạn cung cấp. Hành vi khác nhau, dựa trên cách bạn truy cập phương thức:
Teacher teacher = new Teacher();
Person person = (Person)teacher;
teacher.ShowInfo(); // Prints 'I am a teacher!'
person.ShowInfo(); // Prints 'I am a person!'
Hành vi này có thể được muốn, nhưng trong trường hợp của bạn nó là sai lệch.
Tôi hy vọng điều này làm cho mọi thứ rõ ràng hơn để hiểu cho bạn!