virtual override,virtual和override的作用

  virtual override,virtual和override的作用

  抽象{不能有方法体}

  C #的方法引入了四个修饰符,虚拟的、重写的、密封的和抽象的,以提供不同的继承需求。类的虚方法是在类的继承C#的方法中可以引入虚、重写、密封、抽象四个修饰符,提供不同的继承需求。类的虚方法是一种方法,其实现可以在该类的继承类中更改。当然,这种改变仅限于方法体的改变,而不是方法头(方法声明)的改变。被子类改变的虚方法必须通过在方法头添加override来表示。当调用虚拟方法时,类的实例3354,即对象的运行时类型,确定调用哪个方法体。请看下面的例子:

  使用系统;

  类父级

  {

  公共void F()

  {

  控制台。WriteLine("Parent。f”);

  }

  公共虚拟void G()

  {

  控制台。WriteLine("Parent。g”);

  }

  }

  类别子级:父级

  {

  新的公共void F()

  {

  控制台。WriteLine("子。f”);

  }

  公共覆盖void G()

  {

  控制台。WriteLine("子。g”);

  }

  }

  分类试验

  {

  静态空干管()

  {

  Child b=new Child();

  父母a=b;

  a.f();

  b.f();

  a.g();

  b.g();

  }

  }

  编译并执行程序,输出如下:

  父母。F

  孩子。F

  孩子。G

  孩子。G

  可以看出,子类中f()方法的声明被重写(new)以屏蔽父类中非虚方法f()的声明,而g()方法被重写以提供方法的多态机制。请务必注意,重写方法不同于重写方法。本质上,override方法是一个编译时绑定,而override方法是一个运行时绑定。值得指出的是,虚方法不可能是静态方法3354,也就是说,一个方法不能同时用静态和虚来修饰,这是由其运行时类型判别机制决定的。Override必须和virtual一起使用,当然也不能和static同时使用。

  如果继承系统不想让一个虚方法包含在一个类中,该怎么办?答案是sealed override,可以通过同时用sealed和override修饰一个虚方法来实现:sealed override public void F()。注意,这里必须同时使用sealed和override,而且还必须是密封覆盖的虚方法,或者是覆盖的虚方法(不是密封覆盖的)。封一个非虚的方法是没有意义的,也是错误的。

  抽象方法在逻辑上类似于虚方法,只是它们不能像虚方法一样被调用。它们是接口的声明,而不是实现。抽象方法没有方法实现,也不允许这样做。抽象方法也不能是静态的。包含抽象方法的类必须是抽象的,并且必须添加抽象类修饰符。但是抽象类不一定要包含抽象方法。继承抽象方法的抽象类的子类必须重写并实现(直接使用override)该方法,或者组合使用抽象重写以保持抽象,或者不提供任何重写和实现。后两者的行为是一样的。请看下面的例子:

  使用系统;

  抽象类父类

  {

  公共抽象void F();

  公共抽象void G();

  }

  抽象子类:父类

  {

  公共抽象重写void F();

  }

  抽象类孙子:孩子

  {

  公共重写void F()

  {

  控制台。WriteLine(“孙子。f”);

  }

  公共覆盖void G()

  {

  控制台。WriteLine(“孙子。g”);

  }

  }

  抽象方法可以抽象继承的虚方法。掌握了运行时绑定和编译时绑定的基本机制,就能看透重载、虚、重写、密封、抽象等形式的方法。类,当然这种改变仅限于方法体的改变,而不是方法头(方法声明)的改变。被子类改变的虚方法必须通过在方法头添加override来表示。当调用虚拟方法时,类的实例3354,即对象的运行时类型,确定调用哪个方法体。看下面这个例子:使用Systemclass Parent { public void F(){ Console。WriteLine("Parent。f”);}公共虚拟void G() { Console。WriteLine("Parent。g”);} } class Child:Parent { new public void F(){ Console。WriteLine("子。f”);}公共覆盖void G() { Console。WriteLine("子。g”);} } class Test { static void Main(){ Child b=new Child();父母a=b;a . F();b . F();a . G();b . G();}}}程序编译执行,输出为:parent.fchild.fchild.g可以看到,类child中f()方法的声明已经被覆盖(new)以屏蔽父类中非虚方法f()的声明,而g()方法已经被覆盖以提供方法的多态机制。请务必注意,重写方法不同于重写方法。本质上,override方法是一个编译时绑定,而override方法是一个运行时绑定。值得指出的是,虚方法不可能是静态方法3354,也就是说,一个方法不能同时用静态和虚来修饰,这是由其运行时类型判别机制决定的。Override必须和virtual一起使用,当然也不能和static同时使用。如果不想让一个虚方法覆盖在一个类的继承系统中,该怎么办?答案是sealed override,可以通过同时用sealed和override修饰一个虚方法来实现:sealed override public void F()。注意,这里必须同时使用sealed和override,而且还必须是密封覆盖的虚方法,或者是覆盖的虚方法(不是密封覆盖的)。封一个非虚的方法是没有意义的,也是错误的。抽象方法在逻辑上类似于虚方法,只是它们不能像虚方法一样被调用。它们是接口的声明,而不是实现。抽象方法没有方法实现,也不允许这样做。抽象方法也不能是静态的。包含抽象方法的类必须是抽象的,并且必须添加抽象类修饰符。但是抽象类不一定要包含抽象方法。继承抽象方法的抽象类的子类必须重写并实现(直接使用override)该方法,或者组合使用抽象重写以保持抽象,或者不提供重写和实现。后两者的行为是一样的。看下面这个例子:使用System抽象类Parent { public abstract void F();公共抽象void G();}抽象类Child: Parent {公共抽象覆盖void F();}抽象类孙子:子{公共重写void F() {控制台。WriteLine(“孙子。f”);}公共覆盖void G() { Console。WriteLine(“孙子。g”);}}抽象方法可以抽象继承的虚方法。掌握了运行时绑定和编译时绑定的基本机制,就能看透重载、虚、重写、密封、抽象等形式的方法。

virtual override,virtual和override的作用