如果x和y是私有的话,我无法理解为什么类a中的m()可以通过b类和b类对象访问x和y。我知道当b继承自a时,b接收来自a的私有成员,即使它们不能被b使用。但令我感到奇怪的是,b成员不能使用x和y,而除了a之外的类不能通过b类和b类对象获取变量,而m()可以通过b访问x和y class和b class object。
有人可以使用我错过的一般规则向我解释这个问题,或者可能解释编译器如何将“基础成员”赋予派生类?
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 :(得分:3)
我无法理解为什么如果x和y是私有的,那么a类中的m()可以通过b类和b类对象访问x和y
类声明中的代码可以访问该类声明的任何私有成员 - 就像那样简单。因此a
中的代码无法访问b
中声明的 私有变量,但它可以通过{{1}的实例访问a
中声明的私有变量这也恰好是a
的实例。
注意这一行:
b
有效地转换为
int rr = b.y;
int rr = a.y;
仅由y
声明 - 如果a
声明 ,则无法访问。
有关详细信息,请参阅C#4语言规范的第3.5节。
答案 1 :(得分:0)
这是继承自C ++语言的规则。
private
和protected
对类进行操作,而不是对象。因此,例如,如果您有一个Bank
对象,其成员可以访问任何其他Bank
的私人数据,尽管它可能看似违反直觉或危险。
由于C ++广泛使用指针算法和无限制的类型转换,因此在同一进程中执行任何代码之前,无法可靠地保护进程内的数据。
但是,如果您只需要意外访问的对象级别保护,则可以通过定义接口并仅在银行之间传递接口来帮助实现这一点。虽然Bank
对象仍然可以执行以下操作:
void TransferMoneyFrom(IBank otherBank, decimal theirAccountNumber,
decimal receivingAccountNumber, int amount)
{
((Bank)otherBank).PrivateProperty = whatever;
}
...它不太可能无意中发生,因为需要显式类型转换或使用反射。
(请注意,C#通常会更容易故意访问其他类的私有成员,而这些类的源代码是您没有的(通过名称,使用反射)。如果这种类型的供应商认为这是一个劣势,他们可以使用混淆器来使这更加困难。这仍然无法以任何方式保护混淆对象免受其他实例的影响。)