Protected Member Access

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成员的。

http://blogs.msdn.com/b/ericlippert/archive/2005/11/09/why-can-t-i-access-a-protected-member-from-a-derived-class.aspx

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

 

Google Bard的解答

Protected members can only be accessed by classes that inherit from the class that declares the protected member. This is because protected members are intended to be used by classes that are related to each other, and not by classes that are unrelated.

For example, let's say we have a class called Shape that has a protected member called area. We can then create a derived class called Circle that inherits from Shape. The Circle class can then access the area member, because it is a derived class of Shape.

However, a class that is not related to Shape cannot access the area member. For example, the following code will not compile:

Code snippet
class OtherClass {
  void doSomething() {
    Shape shape;
    shape.area = 10; // This will not compile.
  }
}

This is because the OtherClass class is not related to the Shape class. It is not a derived class of Shape, and it does not have any special access to the Shape class.

There are a few reasons why protected members are not accessible from unrelated classes. One reason is that it helps to protect the data in the class. If protected members were accessible from unrelated classes, then it would be possible for those classes to modify the data in the class in an unauthorized way.

Another reason why protected members are not accessible from unrelated classes is that it helps to enforce the Single Responsibility Principle. The Single Responsibility Principle states that a class should only have one responsibility. If protected members were accessible from unrelated classes, then it would be possible for those classes to add new responsibilities to the class. This could lead to the class becoming too complex and difficult to maintain.

In general, it is best to avoid accessing protected members from unrelated classes. If you need to access a protected member from an unrelated class, then you should consider making the member public. However, you should only do this if you are sure that it is safe to do so.

Sources

 

 

posted @ 2015-05-06 13:38  ChuckLu  阅读(983)  评论(0编辑  收藏  举报