浅谈基类与子类之间继承关系

    公司项目是窗体应用程序,c#开发的。在看代码了过程中遇到了一个疑问,引发了如下思考。

=============问题==================

疑问:要显示的窗体是frmmain是继承自customFrm这样的基窗体的。当我实例化frmmain窗体的时候,(new frmmain()) as customFrm).show().我发现子窗体和父窗体的内容都能全部显示出来。当然我们需要的就是这样。但是问题就来了。既然实例化子类,然后强制转化为父类。那么父类就只能调用父类本身的成员,而无法做到访问子类成员了,那么子类的成员是这么在界面上显示出来的? 写了个简单的demo,具体化这个问题

一个父类B如下:

 public class B
    {
       public B() 
       {
           
       }
      public string strB;
      public virtual void modifyUI_B() 
      {
          Console.WriteLine("I am  B");
      }
    }

一个继承B的子类A

    class A:B
    {
        public A()
        {
       }
        public string strA = "";
        public void show_UI_A()
        {
            Console.WriteLine("I AM A_1");
        }
     }

 我们在主函数main里面写这样的代码:

   B b = (new A()) as B;
            Console.WriteLine("====================");
            b.modifyUI_B();
           // b.show_UI_A();  //无法使用
            Console.ReadKey();

问题具体化后,就是实例化A后,A本身看到是具备B和A的全部特性,强制转化为B类型。那么B不再拥有A的成员。就无法调用A的方法Method_A_1().那么我原先的问题,就出来了,子窗体被实例化强制转化基窗体后,为啥子窗体的内容还是会呈现到界面上

================原因=================

断点调试后,发现原因是这样的。每当子类A实例化的时候,基类B的构造函数会先被执行一遍,然后才是子类A的构造函数被执行一遍,所以后期,即使你强制转化了成了基类,也是只你无权访问子类成员了。但是如果你的子类的显示在构造函数里被相应了,也同样会被显示出来。比如将面的demo该成这样:

 public class B
    {
       public B() 
       {
       }
      public string strB;
      public virtual void modifyUI_B() 
      {
          Console.WriteLine("I am  B");
      }
    }  
    
   class A:B
    {
        public A()
        {
        show_U1_A();
        }
        public string strA = "";
        public void show_UI_A()
        {
            Console.WriteLine("I AM A");
        }
     }
    
    static void Main(string[] args)
        {
            B b = (new A()) as B;
            Console.WriteLine("====================");
            b.modifyUI_B();

            Console.ReadKey();
        }

如果改成上面这种情况,即使我们转化创基类,其实A界面的内容也会被显示出来,因为它在构造函数里面已经被调用了。

然后如果我们还要修饰界面风格,我们可以b.modifyUI_B();可以了。这样两者的的效果就会被叠加显示。这就是为什么实际项目中,子窗体没实例化后强制为基窗体,界面子窗体的内容也能被显示的原因。就是在子类的构造函数上已经初始化了窗体要显示的内容。最后强制的到的基类窗体对象只是无法拥有子窗体的成员而已。

======下面扩展点重写基类的知识======

如果子类重写了基类的方法,然后实例化了子类,再强制转化为基类,那么调用方法响应的拥有时被重写后的方法。

如下:

 public class B
    {
       public B() 
       {
       }
      public string strB;
      public virtual void modifyUI_B() 
      {
          Console.WriteLine("I am  B");
      }
    }  
    
   class A:B
    {
        public A()
        {
        show_U1_A();
        }
        public string strA = "";
        public void show_UI_A()
        {
            Console.WriteLine("I AM A");
        }
        
        public override void modifyUI_B()
         {
         Console.WriteLine("此方法被子类已经重写");
        }   
        
        
    }
    
    static void Main(string[] args)
        {
            B b = (new A()) as B;
            Console.WriteLine("====================");
            b.modifyUI_B();

            Console.ReadKey();
        }

那么我们在子类强制转化为基类后调用modifyUI_B()的时候,其实仍然是调用的子类重写的方法。

大二开始就知道继承和接口什么的,以为自己看懂了,其实很多细节都不懂。。。

你可能感兴趣的:(继承,C#)