new
modifier làm cho thành viên ẩn, phá vỡ mối quan hệ đa hình trong phân cấp lớp của bạn. Phương pháp SayHi
của B
được coi là riêng biệt (không ghi đè) từ A
's (do đó, lựa chọn từ “mới” làm từ khóa). Phương pháp của C
sau đó ghi đè B
, không phải là A
’(vẫn bị ẩn).
Vì vậy, khi bạn gọi SayHi
về một trường hợp C
thông qua một tài liệu tham khảo A
, bộ thực thi sẽ giải quyết nó chống lại các loại A
, không phải là C
loại (trong đó SayHi
là một phương pháp “mới” thừa hưởng từ B
).
Nếu, mặt khác, bạn đã chạy:
B p = new C();
p.SayHi();
... bạn sẽ có được kết quả đa hình dự kiến:
From C
Sửa: Kể từ khi bạn yêu cầu một use-case , đây là một. Trước khi giới thiệu các generic trong .NET Framework 2.0, việc ẩn thành viên đôi khi được sử dụng như một phương tiện thay đổi kiểu trả về của các phương thức kế thừa trong các lớp dẫn xuất (một cái gì đó bạn không thể làm khi ghi đè) để trả về các kiểu cụ thể hơn. Ví dụ:
class ObjectContainer
{
private object item;
public object Item
{
get { return item; }
set { item = value; }
}
}
class StringContainer : ObjectContainer
{
public new virtual string Item
{
get { return base.Item as string; }
set { base.Item = value as string; }
}
}
class QuotedStringContainer : StringContainer
{
public override string Item
{
get { return "\"" + base.Item + "\""; }
}
}
Thuộc tính của lớp ObjectContainer
Item
trả về một đồng bằng object
. Tuy nhiên, trong StringContainer
, thuộc tính được kế thừa này bị ẩn để trả về một số string
thay thế. Như vậy:
ObjectContainer oc = new StringContainer();
object o = oc.Item; // Valid, since ObjectContainer.Item is resolved
string s1 = oc.Item; // Not valid, since ObjectContainer.Item is still resolved
string s2 = ((StringContainer)oc).Item;
// Valid, since StringContainer.Item is now resolved
Lớp QuotedStringContainer
đè Item
tài sản của StringContainer
, kế thừa kiểu string
trở lại của nó; tuy nhiên, nó là vẫn còn bị ẩn khỏi tài sản object
-returning Item
của ObjectContainer
. Nếu nó không phải là cách này, sẽ không có cách dung hòa các loại lợi nhuận khác nhau của họ ...
ObjectContainer oc = new QuotedStringContainer();
object o = oc.Item; // Valid, since ObjectContainer.Item is resolved
string s1 = oc.Item; // Not valid, since ObjectContainer.Item is still resolved
string s2 = ((StringContainer)oc).Item;
// Valid, since QuotedStringContainer.Item is now resolved
// (polymorphism!)
string s3 = ((QuotedStringContainer)oc).Item;
// Valid, since QuotedStringContainer.Item is now resolved
'new' từ 'b' được giấu sự quá tải ảo trong 'C'. Thay đổi 'p' thành kiểu' B' và bạn sẽ thấy đầu ra từ 'C' – asawyer
Câu hỏi đặt ra là" trường hợp sử dụng cho cái này là gì? " nhưng câu hỏi thực sự được hỏi là "tại sao nó lại làm điều này?". Tôi tò mò về trường hợp sử dụng cho điều này là - cố ý đánh bại thừa kế theo cách không rõ ràng đối với người tiêu dùng API của bạn có vẻ vô cùng nguy hiểm. – Chuu
@Chuu: Cảm ơn, tôi đã làm rõ. – dotancohen