2012-06-10 111 views
0

爲什麼m()在類a中可以通過b類和b訪問x和y類對象如果x和y是私有的。我知道,當b從a繼承時,b從a接收私人成員,即使它們不能被b使用。但對我來說奇怪的是,b成員不能使用x和y,而a以外的類不能通過b類和b類對象獲得變量,但m()可以通過b訪問x和y class和b類對象。訪問繼承的私有基類成員...通過派生類對象...在基類成員中創建

有人可以解釋這個給我使用一般規則,我錯過了或者可能解釋如何編譯器這樣'給''基礎成員派生類?

class a 
{ 
    private int x; 
    private static int y; 

    static void m() 
    { 
     b bobj = new b(); 
     int mm = bobj.x; 
     int rr = b.y; 


    } 

    void n() 
    { 
     b bobj = new b(); 
     int mm = bobj.x; 
     int rr = b.y; 
    } 
} 

class b : a 
{ 
    private int u; 
    private static int v; 

    static void o() 
    { 

    } 

    void p() 
    { 

    } 
} 
+0

不知道問題出在哪裏。 'x'和'y'只能在'a'的成員之內被訪問,即使這些是由基類繼承和使用的。 – Oded

回答

3

我不能換我周圍爲什麼M()在課堂上可以通過B類和B類對象訪問x和y,如果x和y是私人

代碼頭在類聲明中可以訪問由該類聲明的任何私有成員 - 就​​像那樣簡單。因此,a中的代碼無法訪問b中的私有變量,但它可以通過a的實例訪問a中聲明的私有變量,該實例也恰好是b的實例。

需要注意的是這一行:

int rr = b.y; 

有效地轉化爲

int rr = a.y; 

y只宣佈a - 如果它真的通過b宣佈,就無法訪​​問。

有關更多詳細信息,請參閱C#4語言規範的第3.5節。

+0

@MareInfinitus:'base.b'沒有任何意義 - 'b'是類型名稱。我建議你編寫你想要檢查它是否真的有意義的代碼... –

+0

它就是這樣! Skeet先生的回答引起了當場的注意。感謝大家! – greenonion

+0

@MareInfinitus:但是當你嘗試使用'bobj'當然是不會有效的...... –

0

這是一個從C++語言繼承的規則。

privateprotected對類而不是對象進行操作。因此,例如,如果您有Bank對象,則其成員可以訪問任何其他Bank的私人數據,儘管它看起來可能違反直覺或危險。

由於C++廣泛使用指針算術和無限類型轉換,因此在任何代碼在同一進程中執行之前無法可靠地保護進程內的數據。

但是,如果您只需要意外訪問的對象級別保護,則可以通過定義接口並僅在銀行之間傳遞接口來提供幫助。雖然Bank對象仍然可以做到以下幾點:

void TransferMoneyFrom(IBank otherBank, decimal theirAccountNumber, 
         decimal receivingAccountNumber, int amount) 
{ 
    ((Bank)otherBank).PrivateProperty = whatever; 
} 

...這不太可能,因爲需要顯式類型轉換或使用反射無意地發生。

(請注意,C#通常更容易故意訪問其他一些類,它的源代碼,你沒有(通過名稱的私有成員,使用反射)。如​​果這被認爲是由一個缺點這種類型的供應商,他們可以使用混淆器來使這變得更加困難,但它仍然不能以任何方式保護混淆的對象免受其他本身的影響。)

相關問題