C#中私有成员的继承

5
在C#中继承类时,私有成员是否被继承? 我已经阅读了一些相关主题,有人说私有成员被继承但无法访问私有成员,有人说在继承类时不会继承私有成员。请解释一下这个概念。如果它被继承了,能否给出一个解释? 谢谢

根据定义,private表示子类无法访问它(除非使用反射)。这就是为什么存在protected的原因。 - Tim Schmelter
我不是在谈论可访问性,我想知道私有成员是否被继承了? - tester
不要使用继承,而应该使用组合。这样问题就不复存在了。 - David Arno
1
@DavidArno,虽然我也赞同这种方法,但每个面向对象的开发人员都应该明白继承是如何工作的。 - weston
@weston,说得好:) - David Arno
10个回答

10

如果我正确理解了你的问题,那么你不关心可访问性,而只关心私有成员是否被继承

答案是肯定的,所有私有成员都被继承,但你不能在没有反射的情况下访问它们。

public class Base
{
    private int value = 5;

    public int GetValue()
    {
        return value;
    }
}

public class Inherited : Base
{
    public void PrintValue()
    {
        Console.WriteLine(GetValue());
    }
}

static void Main()
{
    new Inherited().PrintValue();//prints 5
}

谢谢您的回复,但您能否举个例子来解释这个概念吗? - tester
添加了示例,这样就够了吗? - Sriram Sakthivel
1
+1 这个答案比其他答案更好!做得很好,值得赞扬! - Ramesh Rajendran
1
但在这个例子中,我们正在调用基类的公共方法? - tester
@tester 当然,正如我之前所说的,所有成员都是继承的,并且它们将在原地,但要访问它们,您需要通过辅助方法或属性公开它们 :) - Sriram Sakthivel
显示剩余3条评论

2

你可以将某些内容标记为protected,这样你就可以从派生类型中访问它们。

编辑:就继承而言,是的,子类确实会继承。子类仍然是父类类型,因此继承了所有东西。子类只是不能直接访问它,但如果你调用使用私有父字段的基类方法,那么这将运行良好。


1

就像Sriram所说的,是的,私有成员确实会被继承,但它们不可访问。

如果它们不会被继承,受保护或公共属性引用私有成员将在继承类中断。

class myBase
{
  private string _myProp;
  protected string MyProp
  { 
    get 
    {
      return _myProp;
    }
    set
    {
      _myProp = value;
    }
  }
}
class myChild : myBase
{
  public myChild()
  {
    _myProp = "SomeString"; // This will fail!!!
    this.Myprop = "SomeString"; // This works
  }
}

在子类中,您无法直接访问基类中的私有属性_myProp。但是,该成员已被继承,因此可以通过受保护的属性MyProp进行访问。


1
私有成员无法被继承,只有受保护的成员可以像扩展的私有成员一样。

“Private members can't be inherited” 是什么意思? - Sriram Sakthivel
私有成员只能在定义它们的类中访问,因此如果你继承该类,则除非将其声明为受保护的,否则无法访问该成员。 - Michael27
当然,你是正确的。但是你的回答措辞有误。应该是私有成员虽然被继承但不可访问 - Sriram Sakthivel

0
进一步解释,当内部作用域起作用时,子类可以访问私有成员。例如,以下代码将编译通过:
class A
{
    private int _private;

    class B : A
    {
        void Foo()
        {
            this._private = 2;
        }
    }
}

0

最简单的答案是,您不能直接访问派生类中基类的私有变量,但是当覆盖类对象被初始化时,这些私有对象和值在基类中被初始化(因此继承了基类变量),如果基类公开了某些属性或函数,则可以使用它们来访问它们。
为了使解释更清晰,

    class A 
    {
        private int i;
        private int j;
        protected int k;

        public A()
        {
            i = j = k = 5;
        }
    }


    class B : A
    {
        private int i; //The same variable exist in base class but since it is private I can declare it
        private int j;
        private int k; //Here I get warning, B.k hides inherited member A.k'. Use the new keyword if hiding was intended.   F:\Deepak\deepak\Learning\ClientUdpSocketCommunication\ClientUdpSocketCommunication\Program.cs  210 25  ClientUdpSocketCommunication

        private int l;
        private int m;
        private int n;

        public B()
        {
            i= j = this.k = l = m = n = 7; // Here I have used this.k to tell compiler that I want to initialize value of k variable of B.k class
            base.k = 5; //I am assigning and accessing base class variable as it is protected

        }
    }

如果初始化B类的对象,则A.i,A.j,A.k变量将被初始化,其中B.i,B.j,B.k,B.l变量,如果基类公开函数或属性,则我可以访问所有基类变量。

0

被标记为private的成员只能在定义它们的类型中访问。您无法从派生类型中访问它们。

被标记为protected的成员可以在定义它们的类型和派生类型中访问。

被标记为internal的成员只能从定义该类型的程序集中访问。 您可以组合使用protectedinternal访问修饰符。

当谈论私有成员的值时:它们当然是继承的。派生类始终也是基类的类型。如果基类持有一个私有值来存储一些数据,则派生类也会这样做,只是您无法从派生类中访问该值。

请还阅读MSDN中的可访问性级别相关文章。


0

来自http://msdn.microsoft.com/en-us/library/ms173149.aspx

派生类可以访问基类的公有、保护、内部和受保护的内部成员。虽然派生类继承了基类的私有成员,但它不能访问这些成员。不过,所有这些私有成员仍然存在于派生类中,并且可以执行它们在基类本身中执行的相同工作。例如,假设一个受保护的基类方法访问一个私有字段。该字段必须存在于派生类中,以便继承的基类方法正常工作。


0

你说的关于私有字段被继承的问题是完全正确的。

这里发生了什么:子类将继承基类的行为。该行为可能需要一些字段来工作。因此,您的子类将为它们保留一些空间,但您将无法操作那些字段,只能使用方法(公共和受保护的方法)

换句话说,您的子类通过在内存中保存它们来继承基类字段,但它不能访问它们。

在低级别上,是编译器防止您访问/更改那些私有字段,但即使使用反射,您仍然可以这样做。

如果您需要任何澄清,请告诉我。


Sriram Sakthivel给了一个例子,它是否使用了反射? - tester
不,它并不是这样的。它使用其基类的行为来操作基类的私有方法。 - evhen14

0

简短回答:是的,但您无法直接访问它们。

当类A从类B派生,并且B具有私有属性时,则该属性将存在于派生自类A的实例中。但是,您无法访问它。它必须存在,因为类B中指定的行为取决于它。

趣闻: 实际上,仍然可以使用称为反射的东西访问私有属性。但是不要担心这个问题,除非您真的需要知道正在发生什么以及您正在做什么,否则不应为此目的使用反射。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接