C#之abstract与virtual

Virtual 用于修饰类

定义:在C#中,类的虚拟不是通过关键字virtual来声明的,用abstract修饰的类称为抽象类。抽象类不能实例化,但可以声明它们的变量,这样可以实现多态性。抽象类可以包含三种函数,抽象函数、虚拟函数和普通函数。下面的例子说明了抽象类的作用,即通过将抽象父类赋值为子类来实现多态。

    class Program

    {

        static void Main(string[] args)

        {

            A a = new B();

            a.DoSomething();

            a.DoAnotherThing();

            a.notVirtualFunc();

            Console.ReadKey();

        }

    }

    public abstract class A

    {

        public virtual void DoSomething()

        {

            Console.WriteLine("I'm A!");

        }

        public void notVirtualFunc()

        {

            Console.WriteLine("I'm not Virtual Func A");

        }

        public abstract void DoAnotherThing();

    }

    public class B : A

    {

        public override void DoSomething()

        {

            Console.WriteLine("I'm B!");

        }

        new public void notVirtualFunc()

        {

            Console.WriteLine("I'm not virtual Func but B");       

        }

        public override void  DoAnotherThing()

        {

            Console.WriteLine("I'm B,I'm Doing Another thing");

        }

}

如果抽象类未实现其抽象函数,即例子中class A未实现DoSomething函数,则继承类必须实现该抽象函数,否则编译器会报错。在抽象类中也可以包含非抽象成员函数,如例子中的notVirtualFunc。在子类中实现抽象父类的非抽象成员时,使用的关键字并不是override,而是new。打印结果为:

I‘m B!
       I’m B,I'm Doing Another thing
       I‘m not Virtual Func A 

如果将override替换为new,则会出现如下结果,这说明了override是覆盖了父类的函数,而new仅为子类实现了一个同名函数,这样就不是多态了。

I’m A!
       I’m B,I'm Doing Another thing
       I‘m not Virtual Func A 

需要注意的是,子类必须实现抽象父类的纯虚函数,即抽象父类中没有函数体的函数,这些函数用abstract来修饰而不像C++中用virtual来修饰,如例子中,如果类B中没有函数DoAnotherThing的话编译器会报错。

Virtual 用于修饰成员函数

Virtual修饰的函数可以出现在非抽象类或者抽象类中。下面的例子与上一章的例子相似。

    class Program

    {

        static void Main(string[] args)

        {

            A a = new B();

            a.DoSomething();

            a.DoAnotherThing();

            A a1 = new A();

            a1.DoSomething();

            a1.notVirtualFunc();

            Console.ReadKey();

        }

    }

    public class A

    {

        public virtual void DoSomething()

        {

            Console.WriteLine("I'm A!");

        }

        public void DoAnotherThing()

        {

            Console.WriteLine("This is A!");

        }

    }

    public class B : A

    {

        public override void DoSomething()

        {

            Console.WriteLine("I'm B!");

        }

        new public void DoAnothingThing()

        {

            Console.WriteLine("This is B!");

        }

}

这个例子与上一个例子很像,但是不同点在于这个例子中的父类是普通的类,所以它可以进行实例化,而得到的结果也基本与上一个例子相同。

I’m B!
      I'm not Virtual Func A
      I'm A!
      I‘m not Virtual Func A 

需要注意的是,仅在抽象类中可以使用纯虚函数,即abstract修饰的成员函数,而未使用virtual修饰的函数,也不可以用override来覆盖,只可以使用new来生成一个新的同名函数。

区分一下virtualabstract,就是abstract修饰的是抽象的用于继承的类或者成员函数,而virtual修饰的是可用于覆盖父类的成员函数。

接口类

接口类可以理解为一种特殊的抽象类,对应C++中的纯虚类。在C#中,接口的成员不允许使用publicprivate等修饰符,强制定义为公共的;接口成员函数不能包含代码体,只能在继承接口的类中实现,并且非抽象类必须实现接口的所有成员函数,只有子抽象类的抽象函数才可以不实现接口的成员函数;接口的成员函数不能用virtualabstract来定义。

    class Program

    {

        static void Main(string[] args)

        {

            interfaceBase base1 = new B();

            interface1 face1 = new B();

            base1.interfaceFunc();

            face1.interfaceFunc();

            Console.ReadKey();

        }

    }

    interface interfaceBase

    {

        void interfaceFunc();

    }

    interface interface1 : interfaceBase

    {

        new void interfaceFunc();

    }

    public class B : interface1

    {

        public void interfaceFunc()

        {

            Console.WriteLine("I'm B");

        }

}  

这个例子的结果如下:

I’m B
      I'm B 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值