2017-02-05 227 views
1

一个疑问,我有两个类名为一个
基类派生类。 B类继承A类的两个数据成员和两个成员函数。传承 - 无法访问基类的数据成员在派生类中继承

在派生类,访问静态数据成员是工作,但 访问非静态数据成员给出错误。对于成员函数,同样的情况也是 。我无法访问非静态成员函数。

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

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

reference Image

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();   
    } 
} 
+0

把代码,而不是它的图片。所以我们可以复制它。 –

+0

@Farzin Kanzi在我的问题中添加的代码请检查它 –

+0

好吧,'alert'是一种实例方法。如果没有第一个类的实例,就无法访​​问它。 – CKing

回答

7

这一行是非法的:

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#中的方法通常以大写字母开头。

另外,在这段代码中没有很好的理由来进行复制。您已经可以从派生类访问基类成员,那么为什么要将它们复制到派生类中呢?

+0

你解释了**,**,程序没有逻辑,我只是​​为解释我的问题而创建的 –

0

调用setter方法中的非静态方法:

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

    class B :A 
    { 
     private string s; 

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

它是一个很好的答案。您可以在子类的方法中使用继承的对象。 –

+0

@AliEzzatOdeh,好的,为什么我不能直接访问它。 –

+0

因为非静态方法是每个实例,所以你不能直接调用非静态方法,但是你可以从方法的实现中调用它,这里是setter,它赢得了'除非创建了一个对象,否则不会被调用。 另一方面,静态方法为所有对象共享,因此可以在不创建对象的情况下调用它(直接从类中调用)。 –

1

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

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

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

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

现在让我们去非静态字段。这里是你的班级,请注意号码的评论:

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.
相关问题