2010-03-03 44 views
21

Đây là số extension cho số question này được hỏi một giờ trước.ghi đè nội bộ được bảo vệ bằng bảo vệ!

Chúng tôi không thể sửa đổi access modifiers khi ghi đè virtual method trong lớp derived. Hãy xem xét Control lớp trong System.Web.UI namespace

public class Control : IComponent, IDisposable,... 
{ 
    protected internal virtual void CreateChildControls() 
    { } 
    . 
    . 
} 

Bây giờ xem xét này

public class someClass : System.Web.UI.Control 
    { 
     // This should not compile but it does 
     protected override void CreateChildControls() 
     { } 

     // This should compile but it does not 
     protected internal override void CreateChildControls() 
     { } 
    } 

bất kỳ cơ thể có thể giải thích điều này? Cảm ơn

Trả lời

43

Chúng tôi không thể sửa đổi công cụ sửa đổi truy cập khi ghi đè phương thức ảo trong lớp dẫn xuất.

Tuyên bố đó là sai. Bạn có thể và phải thay đổi công cụ sửa đổi truy cập khi ở đúng tình huống bạn mô tả. Trong các tình huống khác, bạn không được thay đổi bộ điều chỉnh truy cập.

tôi giới thiệu bạn đến phần 10.6.4 của đặc tả, trong đó nêu:

một tuyên bố ghi đè không thể thay đổi khả năng tiếp cận của phương pháp ảo . Tuy nhiên, nếu phương pháp cơ sở bị ghi đè được bảo vệ bên trong và , nó được khai báo trong một cụm khác so với lắp ráp có chứa phương pháp ghi đè sau đó ghi đè quyền truy cập được tuyên bố là .

Lý do rất đơn giản.

Bạn, Asad, có tài khoản ngân hàng, BankAccount.

Bạn có một Ngôi nhà. Bạn thuê một căn phòng trong nhà cho người bạn thân nhất của bạn Charlie.

Charlie có con trai, David, sống trong một căn hộ.

Bạn có con trai, Elroy, sống trong một Chung cư.

Elroy có một đứa con trai, cháu trai của bạn, Frank, sống trong một Yurt.

Elroy có một người bạn tốt nhất là Greg, người đang sống trong Căn hộ với anh ấy.

Bạn cấp quyền truy cập vào tài khoản ngân hàng của bạn cho chính bạn, cho bất kỳ ai sống trong nhà và cho bất kỳ hậu duệ nào của bạn. Vì vậy, những người có thể truy cập vào tài khoản ngân hàng là Asad, Charlie, Elroy và Frank.

David không có quyền truy cập vì anh ấy không phải là bạn, cũng không phải là hậu duệ của bạn, cũng không phải anh ấy sống trong nhà. Rằng anh ta là con của bạn cùng nhà của bạn là không liên quan; anh ta không có quyền truy cập vào tài khoản ngân hàng của bạn.

Greg cũng không có quyền truy cập vào tài khoản ngân hàng của bạn. Anh ta không phải là hậu duệ của bạn. Anh ta không sống trong nhà. Thực tế là anh ta đang sống với hậu duệ của bạn không cấp cho anh ta những quyền giống như con cháu của bạn.

Bây giờ chúng ta đi đến mấu chốt của vấn đề. Elroy không được phép mở rộng quyền truy cập vào tài khoản ngân hàng của bạn vào Greg. Bạn sở hữu BankAccount đó và bạn đã nói "bản thân mình, hậu duệ của tôi và những người bạn cùng nhà của tôi". Con bạn không có quyền mở rộng khả năng tiếp cận của BankAccount ngoài những gì bạn thiết lập ban đầu.

Khi Elroy mô tả quyền truy cập của anh ta vào BankAccount, anh ấy chỉ được phép nói "Tôi cấp quyền truy cập cho bản thân và hậu duệ của tôi", vì đó là những gì bạn đã cho phép. Anh ta không thể nói "Tôi cấp quyền truy cập vào BankAccount cho chính tôi, con cháu của tôi và cho những cư dân khác của Condo".

Chỉ cần được rõ ràng:

  • tôi và con cháu của tôi có được truy cập = bảo vệ truy cập
  • I và ở chung tôi có thể truy cập = truy cập nội bộ
  • tôi và con cháu của tôi và ở chung tôi có thể truy cập = bảo vệ truy cập nội bộ
  • kiểm soát = Asad
  • CreateChildControls = BankAccount
  • Nhà = System.Web.dll
  • Charlie = bất kỳ loại trong System.Web.dll
  • David = loại có nguồn gốc của Charlie trong lắp ráp Apartment.DLL
  • Elroy = SomeClass
  • Condo = lắp ráp của bạn có chứa SomeClass
  • Greg = một số lớp khác trong Condo.DLL
  • Frank = nguồn gốc loại SomeClass trong Yurt.DLL
  • Yurt = một số lắp ráp khác
+0

Vì vậy, trong tình huống này, điều gì xảy ra khi bạn cùng nhà của cha mẹ cố truy cập vào những gì họ nghĩ là tài khoản ngân hàng của cha mẹ, nhưng đó thực sự là tài khoản ngân hàng của một đứa trẻ? IE: Một cái gì đó trong System.Web.DLL cố gắng gọi Control.CreateChildControls() (thông qua khả năng truy cập nội bộ), nhưng không có quyền truy cập vào someClass.CreateChildControls()? – Tanzelax

+1

Tương tự tốt ... ngoại trừ việc tôi sẽ không cấp quyền truy cập vào tài khoản ngân hàng của mình cho tất cả mọi người sống trong nhà của tôi;) –

+5

@Eric, tương tự thú vị. Một ý nghĩ - có lẽ thay đổi từ * "người có thể truy cập tài khoản ngân hàng của tôi" * thành * "người có thể lái xe của tôi" * có thể làm cho sự tương đồng cộng hưởng tốt hơn với mọi người. – LBushkin

5

Bởi vì, trong khi thuật ngữ khác nhau, hãy ghi đè số đó là protected giữ khả năng hiển thị của thành viên giống nhau. Nếu bạn được phép ghi đè nó là protected internal, thì bạn sẽ đột nhiên phơi bày thành viên với bất kỳ loại nào khác trong hội đồng của bạn.

+0

Downvot e chăm sóc để giải thích? –

2

Phương tiện nội bộ được bảo vệ được bảo vệ HOẶC nội bộ. Vì vậy, nếu bằng cách ghi đè bên ngoài hội đồng ban đầu, bạn được phép đánh dấu nó được bảo vệ bên trong, bạn sẽ cho phép các lớp khác trong cùng một hội đồng như người ghi đè gọi phương thức này. Điều đó có nghĩa là đóng gói nội bộ của cha mẹ gốc sẽ bị vi phạm.

Các vấn đề liên quan