zoukankan      html  css  js  c++  java
  • virtual和abstract

    virtual和abstract都是用来修饰父类的,通过覆盖父类的定义,让子类重新定义。

    它们有一个共同点:如果用来修饰方法,前面必须添加public,要不然就会出现编译错误:虚拟方法或抽象方法是不能私有的。毕竟加上virtual或abstract就是让子类重新定义的,而private成员是不能被子类访问的。

    但是它们的区别很大。(virtual是“虚拟的”,abstract是“抽象的").

    (1)virtual修饰的方法必须有实现(哪怕是仅仅添加一对大括号),而abstract修饰的方法一定不能实现。如对于virtual修饰的方法如果没有实现:

            public class Test1
            {
                public virtual void fun1();
            }

    错误    2    “Test1.fun1()”必须声明主体,因为它未标记为 abstract、extern 或 partial   

    对于abstract修饰的方法如果有实现:

            public abstract class Test2
            {
                public abstract void fun2() { }
            }

    错误    1    “Test2.fun2()”无法声明主体,因为它标记为 abstract   

    (2)virtual可以被子类重写,而abstract必须被子类重写,

    复制代码
        class BaseTest1
        {
           public virtual void fun() { }//必须有实现
        }
        class DeriveTest1:BaseTest1
        {
            //public override void fun() { }
        }
    复制代码

    编译不会出现错误,如果重写了virtual修饰的方法,前面必须添加override(这样就告诉了编译器你要重写虚拟方法),而且必须有实现,否则编译出错;

    复制代码
        abstract class BaseTest2
        {
            public abstract void fun();
        }
        class DeriveTest2 : BaseTest2
        {
            //public override void fun();错误1:没有实现
            //public  void fun() { }  错误2:重写时没有添加override
            //override void fun() { }错误3:虚拟成员或者抽象成员不能是私有的(只要在父类中声明了虚拟成员或抽象成员,即便是继承的也要加上这个限制)
            public override void fun() { }//如果重写方法; 错误:“A.DeriveTest2”不实现继承的抽象成员“A.BaseTest2.fun()”    
    
        }
    复制代码

    (3)如果类成员被abstract修饰,则该类前必须添加abstract,因为只有抽象类才可以有抽象方法。

    (4)无法创建abstract类的实例,只能被继承无法实例化,比如:     BaseTest2 base2 = new BaseTest2();将出现编译错误:抽象类或接口不能创建实例。
    (5)C#中如果要在子类中重写方法,必须在父类方法前加virtual,在子类方法前添加override,这样就避免了程序员在子类中不小心重写了父类方法。

    (6)abstract方法必须重写,virtual方法必须有实现(即便它是在abstract类中定义的方法).

    复制代码
            abstract public class Test
            {
                //public virtual void Prinf();错误:virtual方法必须有实现
                public virtual void Prinf() //abstract类的virtual方法可以不重写;abstract方法必须重写。
                {
                    Console.WriteLine("Abstract Printf...");
                }
    
            }
            public class Class1 : Test
            {
                /*
                public override void Prinf() //派生类中不重写abstract类的virtual方法照样可以运行,不过调用派生类对象的Printf方法时,调用的是父类的。
                {
    
                    Console.WriteLine("Class One Override Printf...");
                }
                 */
            }
    复制代码

     

     

    注释:现在为学习阶段,所以把别人的文章重新敲了一遍,并且添加了代码,文章出处:http://www.cnblogs.com/xingbinggong/archive/2011/07/05/2098454.html

  • 相关阅读:
    nullnullConnecting with WiFi Direct 与WiFi直接连接
    nullnullUsing WiFi Direct for Service Discovery 直接使用WiFi服务发现
    nullnullSetting Up the Loader 设置装载机
    nullnullDefining and Launching the Query 定义和启动查询
    nullnullHandling the Results 处理结果
    装置输出喷泉装置(贪心问题)
    数据状态什么是事务?
    停止方法iOS CGD 任务开始与结束
    盘文件云存储——金山快盘
    函数标识符解决jQuery与其他库冲突的方法
  • 原文地址:https://www.cnblogs.com/wyBlog117/p/4543691.html
Copyright © 2011-2022 走看看