现在的位置: 首页 > 综合 > 正文

C#中的虚方法,抽象类,重写,隐藏,重载的区别与理解

2013年10月14日 ⁄ 综合 ⁄ 共 4958字 ⁄ 字号 评论关闭

发现人家写的比我清析,所以用了别人的东西,呵呵.

 

先说总结方便不记得的时候看一下:

1、   如果父类方法没有加virtual关键字,即不是一个虚方法,则在子类中只能隐藏基类方法

(new),而不能覆盖(override)。

2、如果父类方法加了virtual关键字,即它是一个虚方法,在子类中一样可以隐藏(new)。

3、如果子类实现了父类相同的方法(相同的方法名称及签名),而没有new,在编译时会报警,但

编译仍然能够通过!

4、调用父类方法:base.方法名()

5、abstract类是一个抽象类,不能被实例化,只能继承

6、最后讲讲重载(overload):是在同一个类中的两个或两个以上的方法,拥有相同的方法

名,函数类型也相同,但是参数却不相同,最常见的重载的例子就是类的构造函数。

 

 

实验例子如下:

 

1、虚方法的概念:

                         类中的方法声明前加上了virtual 修饰符,我们称之为虚方法;

                        如:  class A

                                              {

                                                    public virtual void F(){} //虚方法

                       }

                            virtual修饰符表明:该基类(本例中指A类)的派生类(本例中指B类)可以

重写该方法(本例中指方法F())。

                                          如:  class B:A

                                                        {

                                                               public override void F(){} //派生类B重写类A的虚

方法F()

}

 

                与之相对的,没有用virtual 修饰符,我们称之为非虚方法。

1.隐藏

无论父类方法有没有用virtual修饰符,都可以在子类隐藏父类方法,写法如下

  using System;

  class A

    {

         public void F( ){ Console.WriteLine("A.F");}

         public virtual void G( ){ Console.WriteLine("A.G");}//虚方法,在其子类中可以被重写

    }

 

  class B:A

    {

         new public void F( ){ Console.WriteLine("B.F");}

         new public void G( ){ Console.WriteLine("B.G");}

    }

  class Test

    {

         static void Main( )

           {

               B b=new B( );

               A a=b;

               a.F( ); //值为A.F

               b.F( ); //值为B.F

               a.G( ); //值为A.G              

               b.G( ); //值为B.G

           }

    }

如果要继承父类代码,可以用base.方法名()来调用

 

2.重写

(1)重写的概念:

是子类(即派生类)的方法覆盖父类(即基类)的虚方法。

(2)重写的要求:三相同:

         a.方法名称相同

         b.参数列表相同

         c.返回值类型相同

         一句话,只需重写代码体的内容!

(3)重写声明不能更改虚方法的可访问性:重写方法和虚方法必须具有相同的访问级修饰符。例如:虚方法为public的,重新方法也必须是public的。

 

(4)可以重写基方法:必须是虚拟的(virtual)、抽象的(abstract)或重写的(override)。(非虚方法或静态方法是不可以重写的)

(5)不能使用下列修饰符修改重写(override)方法(即该方法中含有override关键字):new、static、virtual、abstract

如:new public override void outwork () //这样写是不可以的

{

      MessageBox.Show("子类的子类(override)下班");

}

(6)重写属性:重写的属性必须与继承属性有完全相同的访问修饰符、类型和属性名,并且重写属性必须是虚拟的(virtual)、抽象的(abstract)或是重写的(override)。

(7)new关键字和override关键字比较:

                        如果使用override重写xx方法,通过父类引用一样只能看到重写后的方法; override重写的是虚方法,那么就只剩下重写以后的方法,原来的方法被覆盖了。

 

 

如果使用new隐藏xx方法,父类子类引用各自对应方法;

new隐藏基类的方法,那么基类的方法和当前类的方法同时存在只是被隐藏了。

总结:override可以覆盖基类的方法,让基类的方法以子类的内容实现,而new不用来覆盖基类的方法,而是全新定义一个子类的方法,这个方法只属于子类,与基类的方法无关,只是名字上相同而已。

举例说明:

例一:

  using System;

  class A

    {

         public void F( ){ Console.WriteLine("A.F");}

         public virtual void G( ){ Console.WriteLine("A.G");}//虚方法,在其子类中可以被重写

    }

 

  class B:A

    {

         new public void F( ){ Console.WriteLine("B.F");}

         public override void G( ){ Console.WriteLine("B.G");}

}

 

  class Test

    {

         static void Main( )

           {

               B b=new B( );

               A a=b;

               a.F( ); //值为A.F

               b.F( ); //值为B.F

               a.G( ); //值为B.G,因为虚方法G()被重写了

               b.G( ); //值为B.G

           }

    }

例二:

class A  

  {  

      public   virtual   void   F()   {   Console.WriteLine("A.F");   }  

  }  

  class B: A  

  {  

      public   override   void   F()   {   Console.WriteLine("B.F");   }  

  }  

  class C: B  

  {  

      new   public   virtual   void   F()   {   Console.WriteLine("C.F");   }  

  }  

  class D: C  

  {  

      public   override   void   F()   {   Console.WriteLine("D.F");   }  

  }  

  class Test  

  {  

      static   void   Main()  

  {  

             

           D d = new D();  

           C c = d;

           B b = d;

           A a = d;                

           a.F();  //值为B.F 

           b.F();  //值为B.F

           c.F();  //值为D.F 

           d.F();  //值为D.F 

        }  

  }

例三:abstract和override使用方法:注:只有当类是abstract时才可以声明abstract方法;

    abstract class Animal

    {

        public abstract void Drink();

        public abstract void GotoBed();

    }

    class Dog : Animal

    {

        public override void Drink()

        {

            MessageBox.Show("小狗喝水");

        }

        public override void GotoBed()

        {

            MessageBox.Show("小狗睡觉");

        }

        public override string ToString()//也可:public new string ToString()

        {

            return "小狗";

        }

    }

 

总结:

Public abstract void pay();           abstract方法没有方法实现,必须继承

Public sealed override void pay(){}  sealed方法必须是重写父类的方法

Public static void pay(){}               static方法通过类名访问

Public virtual void pay(){}              virtual方法子类可以对其override或new

Public new void pay(){}                父类的方法pay不一定是virtual也可以为非虚方法

Public override void pay(){}             父类的方法pay一定要是virtual

 

例四:new、abstract、virtual、override关键字的使用代码示例:

public abstract class People //abstract说明类People是一个抽象类不能被实例的,只能被继承

    {

        public People()//构造函数

         {

         }

 

        public void Work() //非虚方法

         {

            MessageBox.Show("开始工作!");

         }

 

        public virtual void GetOffWork() //虚函数,说明此方法可以被子类重写覆盖(override)

         {

            MessageBox.Show("下班啦!");

         }

    }

 

public class Manage:People //继承Popele类

    {

        public Manage()//构造函数

         {

         }

        new public void Work()

                      /*因为基类已经实现了Work方法,而在子类中又实现了Work方法,所以编译会报警,在前面加上 new(隐藏基类方法),是将警报关闭,这样就不会报错。*/

         {

            base.Work(); //调用基类Popele的方法。显示“开始工作”

         }

 

        public override void GetOffWork() //重写覆盖people类的方法

         {

            MessageBox.Show("管理员下班啦");

         }

    }

 

抱歉!评论已关闭.