https://msdn.microsoft.com/en-us/library/bcd5672a.aspx
官方的说法The protected keyword is a member access modifier. A protected member is accessible within its class and by derived class instances.
protected关键字是一个成员访问修饰符。一个protected的成员,一个protected成员,在其所在的类中,可由其派生类的实例访问。
可访问性级别的介绍:
https://msdn.microsoft.com/en-us/library/ba0a1yw2.aspx
protected :Access is limited to the containing class or types derived from the containing class.
protected关键字:只能由包含的类进行访问,或者从包含该成员的类所派生的类进行访问。
疑惑的地方:错误观点我本以为只要是派生类的实例,就可以访问受保护的成员。
子类的实例,可以赋值给父类类型的变量。通过父类类型的变量,是不允许访问protected成员的。
A question I got recently was about access to protected methods from a derived class.
Clearly that’s what “protected” means – that you can access it from a derived class.
In that case, why doesn’t this work?
/// <summary>
/// 有蹄类动物
/// </summary>
class Ungulate
{
protected void Eat()
{
/* whatever */
}
} /// <summary>
/// 长颈鹿
/// </summary>
class Giraffe : Ungulate
{
public static void FeedThem()
{
Giraffe g1 = new Giraffe();
Ungulate g2= new Giraffe();
g1.Eat(); // fine
g2.Eat(); // compile-time error “Cannot access protected member”
}
}
What the heck?
Giraffe is derived from Ungulate, so why can’t it always call the protected method?
To understand, you have to think like the compiler.
The compiler can only reason from the static type information, not from the fact that we know that at runtime //reason from 根据...进行推论
g2 actually will be a Giraffe. For all the compiler knows from the static type analysis, what we’ve actually got here is
/// <summary>
/// 有蹄类动物
/// </summary>
class Ungulate
{
protected virtual void Eat()
{
/* whatever */
}
} /// <summary>
/// 斑马
/// </summary>
class Zebra : Ungulate
{
protected override void Eat()
{
/* whatever */
}
} /// <summary>
/// 长颈鹿
/// </summary>
class Giraffe : Ungulate
{
public static void FeedThem()
{
Giraffe g1 = new Giraffe();
Ungulate g2 = new Zebra();
g1.Eat(); // fine
g2.Eat(); // compile-time error “Cannot access protected member”
}
}
We can call Ungulate.Eat legally from Giraffe,
but we can't call the protected method Zebra.Eat from anything except Zebra or a subclass of Zebra.
Since the compiler cannot determine from the static analysis that we are not in this illegal situation, it must flag it as being illegal.
总结,protected成员的使用。
1.在包含该成员的类的内部使用。
2.在派生类的内部使用
3.需要注意的是,派生类的实例对象,想要调用protected成员的时候,不能由第三方进行调用。
派生类的实例对象,可以在包含protected的成员里面,或者子类里面。调用protected成员。
这里的派生类,只有一个层次。
class A
{
protected int Number;
}
class B:A
{
}
class C:B
{
B b = new B();
//如果尝试访问Number的话会提示错误。 protected的成员,必须由类B或者B的派生类才可以访问。
//b.Number=10;
}
在类C中可以有B的实例,但是无法在C中通过B的实例去访问protected成员Number。
因为在C从B进行继承的时候,C中Number的父类是B而不是A。
所以,protected成员,只能在本身包含的类中使用,或者派生类中使用。这里的父类,只包含一个层级。
参考资料
Why Can’t I Access A Protected Member From A Derived Class?
Why Can’t I Access A Protected Member From A Derived Class, Part Two: Why Can I?
Why Can’t I Access A Protected Member From A Derived Class, Part Three
Protected Member Access, Part Four
Protected Semantics, Part Five: More on immutability