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

 

 

作者:Chuck Lu    GitHub    
posted @   ChuckLu  阅读(1006)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示