C#类中方法的执行顺序是什么

作者:犁痕 时间:2022-07-01 03:55:15 

有些中级开发小伙伴还是搞不太明白在继承父类以及不同场景实例化的情况下,父类和子类的各种方法的执行顺序到底是什么,下面通过场景的举例来重新认识下方法的执行顺序:

(下面内容涉及到了C#中的继承,构造函数,虚方法,虚方法的重写,new关键字等知识点)

场景一

有子类继承,但是只实例化父类:只执行A对象,输出A对象的信息


class A
{    
   public A() => Console.WriteLine("A的构造函数");    
   public virtual void Fun() => Console.WriteLine("A的方法");    
}
class B : A
{
   public B() => Console.WriteLine("B的构造函数");    
   public void Fun() => Console.WriteLine("B的方法");    
}
class Program
{
   static void Main(string[] args)
   {
       A a = new A();
       a.Fun();
       Console.ReadLine();
   }
}

上述Main方法中在new A对象时,程序首先进入class A中,执行class A的构造函数A(),然后执行class A中的Fun()方法,故运行结果为:

C#类中方法的执行顺序是什么

场景二

实例化子类,子类和父类的构造函数的执行顺序:当执行B对象时,因为继承A对象,所以首先执行基类A的构造函数


class A
{  
   public A() => Console.WriteLine("A的构造函数");    
   public virtual void Fun()=>  Console.WriteLine("A的方法");    
}
class B : A
{
   public B() => Console.WriteLine("B的构造函数");  
   public void Fun() => Console.WriteLine("B的方法");    
}
class Program
{
   static void Main(string[] args)
   {
       B b = new B();
       b.Fun();
       Console.ReadKey();
   }
}

上述Main方法中在new B对象时,由于B继承A,先执行父类的构造函数,所以先执行A中的构造函数A(),然后在执行B中的构造函数B(),故运行结果为:

C#类中方法的执行顺序是什么

场景三

父类有虚方法,子类没有使用(override)关键字重写父类方法的时候,使用的是new关键字时:


class A
{  
   public A()=>  Console.WriteLine("A的构造函数");  
   public virtual void Fun() => Console.WriteLine("A的方法");

}
class B : A
{
   public B() => Console.WriteLine("B的构造函数");    
   //不写new时,该方法会抛出警告,但不是错误
   public new void Fun()=> Console.WriteLine("B的方法");    
}
class Program
{
   static void Main(string[] args)
   {
       A a = new B();
       a.Fun();
       Console.ReadKey();
   }
}

上述Main方法中先new B对象,先执行A中的构造函数A(),然后在执行B中的构造函数B(),最后调用class A的Fun()方法(没有重写父类方法),故运行结果为:

C#类中方法的执行顺序是什么

场景四

父类有虚方法, 当子类重写了(override)父类的方法时:


class A
{
   public A()=> Console.WriteLine("A的构造函数");    
   public virtual void Fun() =>  Console.WriteLine("A的方法");    
}
class B : A
{
   public B()=> Console.WriteLine("B的构造函数");    
   public override void Fun()=> Console.WriteLine("B的方法");    
}
static void Main(string[] args)
{
   A a = new B();
   a.Fun();
   Console.ReadKey();
}

上述Main方法同样是先new B对象,先执行A中的构造函数A(),然后在执行B中的构造函数B(),但是子方法中使用了override关键字“覆盖”,使得子类中方法覆盖了父类中的方法,无法再访问父类中原始方法。(要重写方法,父类方法必须有virtual关键字),所以其运行结果为:

C#类中方法的执行顺序是什么

场景五

基类是接口层,多重继承时:


interface I
{
   void Fun();
}
class A : I
{
   public A() => Console.WriteLine("A的构造函数");
   public virtual void Fun() => Console.WriteLine("A的方法");
}
class B : A
{
   public B() => Console.WriteLine("B的构造函数");
   //不写new时,该方法会抛出警告
   public new void Fun() =>Console.WriteLine("B的方法");  
}
static void Main(string[] args)
{
   B b = new B();
   b.Fun();
   ((A)b).Fun();
   ((I)b).Fun();
   Console.ReadKey();
}

打印结果:

C#类中方法的执行顺序是什么

场景六

当多重继承,子类重写override父类方法时:


interface I
{
   void Fun();
}

class A : I
{
   public A() => Console.WriteLine("A的构造函数");
   public virtual void Fun() => Console.WriteLine("A的方法");

}
class B : A
{
   public B() => Console.WriteLine("B的构造函数");    
   public override void Fun() =>Console.WriteLine("B的方法");  
}
static void Main(string[] args)
{
   B b = new B();
   b.Fun();
   ((A)b).Fun();
   ((I)b).Fun();
   Console.ReadKey();
}

打印结果:(对比场景5)

C#类中方法的执行顺序是什么

场景七

使用new重写父类方法,同时让每个子类都继承接口:


interface I
{
   void Fun();
}

class A : I
{
   public A() => Console.WriteLine("A的构造函数");
   public virtual void Fun() => Console.WriteLine("A的方法");

}
class B : A, I
{
   public B() => Console.WriteLine("B的构造函数");
   //不写new时,该方法会抛出警告
   public new void Fun() => Console.WriteLine("B的方法");
}
static void Main(string[] args)
{
   B b = new B();
   b.Fun();
   ((A)b).Fun();
   ((I)b).Fun();
   Console.ReadKey();
}

打印结果:

C#类中方法的执行顺序是什么

来源:https://www.cnblogs.com/xiglingui/p/14809348.html

标签:C#,类,方法,执行顺序
0
投稿

猜你喜欢

  • java实现mongodb的数据库连接池

    2023-11-23 14:23:09
  • Java实例讲解Comparator的使用

    2021-07-15 09:16:58
  • Java emoji持久化mysql过程详解

    2023-10-10 23:11:49
  • Java 方法的定义与调用详解

    2023-11-04 13:52:58
  • Spring4下validation数据校验无效(maven)的解决

    2022-01-24 03:01:04
  • 基于SpringMVC入门案例及讲解

    2023-04-06 17:34:43
  • Java原生服务器接收上传文件 不使用MultipartFile类

    2023-11-09 19:31:36
  • JAVA内部类示例详解及练习

    2023-04-05 06:42:39
  • 一文搞懂MyBatis多数据源Starter实现

    2023-07-19 03:34:22
  • Java异常处理try catch的基本使用

    2023-11-24 05:04:38
  • 详解Servlet3.0新特性(从注解配置到websocket编程)

    2023-08-08 14:29:48
  • Java中finally和return的关系实例解析

    2023-05-31 04:21:31
  • Spring JPA学习之delete方法示例详解

    2021-11-23 12:22:55
  • 使用Java的Lucene搜索工具对检索结果进行分组和分页

    2022-07-27 05:21:17
  • java 动态生成bean的案例

    2023-08-09 02:20:05
  • 解决javaWEB中前后台中文乱码问题的3种方法

    2023-03-22 22:39:26
  • Java中遍历Map的六种方法实现

    2022-03-21 13:30:58
  • Java动态代 理分析及简单实例

    2023-11-24 21:14:56
  • Java设计模式之备忘录模式实现对象状态的保存和恢复

    2023-08-28 15:22:27
  • 实例详解Java调用第三方接口方法

    2023-10-15 06:34:32
  • asp之家 软件编程 m.aspxhome.com