繁体   English   中英

继承-无法访问派生类中的基类数据成员

[英]Inheritance - Can't access base class data member in derived class

在继承方面存在一个疑问,我有两个名为AB的类。
A基类B派生类 B类继承了A类的两个数据成员和两个成员函数。

在派生类中,访问静态数据成员正在运行,但是访问非静态数据成员会出错。 成员函数也是如此。 我无法访问非静态成员函数。

如果我访问静态或非静态变量| 内部的任何派生类的功能它做工精细功能

为什么我不能在课堂上直接访问。 为什么在我访问任何派生类函数内部时未显示错误。 请任何人澄清我的疑问。

参考图片

 class A
{
    protected string msg1;
    protected static string msg2;

    protected  string alert1() {
        return "Welcome";
    }
    protected static string alert2()
    {
        return "Welcome All";
    }
}
class B : A {

    string copyMsg1 = msg1;
    string copyMsg2 = msg2;

    string getMsg1 = alert1();
    string getMsg2 = alert2();

    void display() {
        msg1 = "";
        msg2 = "";
        alert2();           
    }
}

这行是非法的:

string getMsg1 = alert1();

因为它相当于

string getMsg1 = this.alert1();

并且在字段初始化程序中访问this是非法的。 为什么? 因为字段初始值设定项在派生类构造函数或基类构造函数之前运行,因此您可能正在调用依赖于构造函数已经运行的方法

正确的解决方案是将您的初始化放入构造函数中:

class B : A {
  string copyMsg1;
  string copyMsg2; 
  string getMsg1;
  string getMsg2;

  public B() 
  {
    this.copyMsg1 = this.msg1;
    this.copyMsg2 = A.msg2; 
    this.getMsg1 = this.alert1();
    this.getMsg2 = A.alert2();
  }

构造的主体中的派生类,基础类字段初始化,和基类的构造体的场的初始化运行。 派生的构造函数主体最后运行,因此您知道它访问的所有内容都已创建。

当我们讨论它时:请注意,C#中的方法传统上以大写字母开头。

另外,此代码中根本没有显示进行复制的充分理由。 您已经可以从派生类访问基类成员,那么为什么要将它们复制到派生类中?

如果我访问静态或非静态变量| 任何派生类函数中的函数正常工作。

为什么我不能在课堂上直接访问。 为什么在我访问任何派生类函数内部时未显示错误。 请任何人澄清我的疑问。

换句话说,您的问题是:为什么我可以在类级别(在任何方法或属性之外)访问静态字段,但不能访问实例字段。

静态字段是每个类的。 您不需要该类的实例,但是您需要该类可用。 因此,如果该类可用,则可以访问它。

现在让我们转到非静态字段。 这是您的课程,请注意注释中的数字:

class B : A {

    string copyMsg1 = msg1; <-- 1. assign non-static to non static 
    string copyMsg2 = msg2; <-- 2. assign static to non static

    string getMsg1 = alert1(); <-- 3. non static calling non-static
    string getMsg2 = alert2(); <-- 4. non static calling static

    void display() {
        msg1 = "";
        msg2 = "";
        alert2();           
    }
}
  1. 这是不允许的,因为它们都是实例字段(非静态),并且不能保证此时有A实例可用。
  2. 这是允许的,因为实例字段可以访问静态字段。 但不是相反,因为实例可能不可用。 实例字段,方法和属性可以访问静态和非静态。
  3. 由于上述项目1,因此不允许这样做。
  4. 由于2而被允许。

在setter方法内调用非静态方法:

class A
   {
       protected string alert()
       {
           return "me";
       }
   }

    class B :A
    {
        private string s;

        private void setS()
        {
            s = alert();
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM