zoukankan      html  css  js  c++  java
  • C#中的abstract、virtual、interface关键字

    一、Virtual(虚方法修饰关键字)


         virtual 关键字用于在基类中修饰方法。virtual的使用会有两种情况:

         情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法。那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法。

         情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法。那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法。

    二、Abstract(抽象方法修饰关键字)

         abstract关键字用在抽象类中修饰方法,并且没有具体的实现。抽象方法的实现必须在派生类中使用override关键字来实现,抽象类就是用来被继承的;可以看成是没有实现体的虚方法;如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其他一般方法;

    三、interface (接口修饰关键字)

    区别:抽象类是一个不完全的类,是对对象的抽象,接口是一种行为规范。

    示例:

    namespace Community.BLL.Demo
    {
        /// <summary>
        /// 接口定义,接口只提供一些方法规约,不提供方法主体。方法不能用public abstract等修饰, 无字段变量,无构造函数。
        /// </summary>
        public interface IPerson
        {
            void getName();//不包含方法主体
            void getAge(string s);//方法可包含参数。
        }
        /// <summary>
        /// 接口实现
        /// </summary>
        public class Chinese : IPerson
        {
            public Chinese() { } //添加构造
            public void getName() { } //实现getName()
            public void getAge(string s) { } //实现getAge()
        }
    
        /// <summary>
        /// 抽象类定义
        /// abstract:声明抽象类、抽象方法
        /// 1.抽象方法所在类必须为抽象类
        /// 2.抽象类不能直接实例化,必须由其派生类实现。
        /// 3.抽象方法不包含方法主体,必须由派生类以override方式实现此方法,这点跟interface中的方法类似
        /// 
        /// </summary>
        public abstract class BaseQuery
        {
            /// <summary>
            /// 构造函数
            /// </summary>
            public BaseQuery() { }
    
            /// <summary>
            /// 抽象方法定义,不含主体,abstract关键字修饰方法,并且没有具体的实现。抽象方法的实现必须在派生类中使用override关键字来实现。
            /// </summary>
            public abstract void Run(QueryRecord queryRecord);
    
            /// <summary>
            /// 一般方法,若在派生类中重写,须使用new关键字
            /// </summary>
            public void StartQuery(QueryRecord queryRecord, dynamic queryParams)
            {
                var objA = new { queryParams.Name, queryParams.IdentifyNumber };
                var objB = new { objA };
            }
            /// <summary>
            /// 虚方法,可覆盖,不是必须的
            /// </summary>
            public virtual void GetName()
            {
            }
        }
    
        /// <summary>
        /// 派生类定义001
        /// </summary>
        public class Query001 : BaseQuery
        {
            /// <summary>
            /// 派生类中使用override关键字来实现基类中的抽象方法
            /// </summary>
            public override void Run(QueryRecord queryRecord)
            {
                var queryParams = new { queryRecord.Name, queryRecord.IdentifyNumber };
                //调用基类中的方法
                base.StartQuery(queryRecord, queryParams);
                //没有重写该虚方法。那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法。
                base.GetName();
            }
            /// <summary>
            /// 使用override重写该方法。那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法。
            /// </summary>
            public override void GetName() { }
    
            /// <summary>
            /// 一般方法,若在派生类中重写,须使用new关键字
            /// </summary>
            new public void StartQuery(QueryRecord queryRecord, dynamic queryParams)
            {
            }
        }
    
        /// <summary>
        /// 派生类定义002
        /// </summary>
        public class Query002 : BaseQuery
        {
            /// <summary>
            /// 派生类中使用override关键字来实现基类中的抽象方法
            /// </summary>
            public override void Run(QueryRecord queryRecord)
            {
                var queryParams = new { queryRecord.Name, queryRecord.IdentifyNumber, Mobile = "138888888", CreateDate = DateTime.Now };
                //调用基类中的方法
                base.StartQuery(queryRecord, queryParams);
            }
        }
        /// <summary>
        /// 查询记录
        /// </summary>
        public class QueryRecord
        {
            public string Name { get; set; }
            public string IdentifyNumber { get; set; }
            public string QueryType { get; set; }
        }
    
        /// <summary>
        /// 调用抽象方法
        /// </summary>
        public class QueryBLL
        {
            /// <summary>
            /// 动态调用不同的类(Query001、Query002)
            /// </summary>
            public void RunQuery()
            {
                List<QueryRecord> list = new List<QueryRecord>();
                list.Add(new QueryRecord() { Name = "张三", IdentifyNumber = "110111000000000001", QueryType = "Query001" });
                list.Add(new QueryRecord() { Name = "李四", IdentifyNumber = "110111000000000002", QueryType = "Query002" });
    
                foreach (QueryRecord queryRecord in list)
                {
                    var queryType = queryRecord.QueryType;
                    string assemblyName = this.GetType().Assembly.GetName().Name;
                    var path = string.Format("{0}.{1},{2}", this.GetType().Namespace, queryType, assemblyName);
                    BaseQuery obj = (BaseQuery)Activator.CreateInstance(Type.GetType(path));
                    obj.Run(queryRecord);
                }
            }
        }
    
    }
    View Code

    单元测试

            #region 调用抽象类测试
            [TestMethod]
            public void CallAbstractClassTest()
            {
                QueryBLL bll = new QueryBLL();
                bll.RunQuery();
            } 
            #endregion
  • 相关阅读:
    hibernate建表默认为UTF-8编码
    XML和JSON
    chrome 模拟发送请求的方法
    什么时候需要使用缓存?
    eclipse中查找类、方法及变量被引用的地方
    用户内容与商业
    2019第48周日
    ajax与重定向
    ifream
    Windows下找到JVM占用资源高的线程
  • 原文地址:https://www.cnblogs.com/hofmann/p/12482733.html
Copyright © 2011-2022 走看看