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

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值