zoukankan      html  css  js  c++  java
  • Abstract(抽象)

    谈到抽象,就先谈谈面向对象语言的三大特性,也是人们口中常说的封装、继承、多态。

    封装:什么是封装,按到我的理解,封装就是把某些类的相关属性和方法封装,对内实现数据影城,对外提供稳定接口。

    继承:从字面上理解,就是声明一个父类,然后子类可以继承,并且子类拥有父类的一切属性和方法。

    多态,值一个类实例相同的方法不同情形有不同表现形式

    讲完这些说说主题,抽象类和接口。

    先来说说抽象类:

    1)抽象类的本质还是一个类,里面可以包含一切类可以包含的
    2)抽象成员 必须包含在抽象类里面,抽象类还可以包含普通成员
    3)继承抽象类后,必须显示的override其抽象成员
    4)抽象类不能直接实例化,声明的对象只能使用抽象类里的方法,不能用子类新增的方法
    5)父类只有一个

    比如说声明一个手机的抽象类,手机又打电话,品牌,系统等一些基本属性。

    public abstract class BasePhone
        {
            public int Id { get; set; }
            public string Name = "123";
            public delegate void DoNothing();
            public event DoNothing DoNothingEvent;
    
            public void Show()
            {
                Console.WriteLine("这里是Show1");
            }
            public virtual void ShowVirtual()
            {
                Console.WriteLine("这里是Show");
            }
    
            /// <summary>
            /// 品牌
            /// </summary>
            /// <returns></returns>
            public abstract string Brand();
    
            /// <summary>
            /// 系统
            /// </summary>
            /// <returns></returns>
            public abstract string System();
    
            /// <summary>
            /// 打电话
            /// </summary>
            public abstract void Call();
    
    
            /// <summary>
            /// 拍照
            /// </summary>
            public abstract void Photo();
    
            public abstract void Do<T>();
        }
    

    然后有一台苹果手机;应该怎么做呢,这时候就可以继承这个抽象类。

        public class iPhone : BasePhone
        {
            /// <summary>
            /// 品牌
            /// </summary>
            /// <returns></returns>
            public override string Brand()
            {
                return "iPhone";
            }
    
            /// <summary>
            /// 系统
            /// </summary>
            /// <returns></returns>
            public override string System()
            {
                return "IOS";
            }
    
            /// <summary>
            /// 打电话
            /// </summary>
            public override void Call()
            {
                Console.WriteLine("User{0} {1} {2} Call", this.GetType().Name, this.Brand(), this.System());
            }
    
            /// <summary>
            /// 拍照
            /// </summary>
            public override void Photo()
            {
                Console.WriteLine("User{0} {1} {2} Call", this.GetType().Name, this.Brand(), this.System());
            }
    
    
            public override void Do<T>()
            {
    
            }
         
        }
    

    那如果这台手机需要实现一个支付功能呢,怎么办,可以在苹果手机类中添加一个支付功能,但是手机不只是有苹果,还有别的品牌,如果都有支付功能,不可能在每个类中都添加一个这样的方法吧,这样太麻烦了,有人会讲,在抽象类中抽象一个支付方法,但是在抽象类中添加了方法,所有继承了这个类的都需要实现这个方法,这样太不方便了,这个时候就需要接口。

    1)接口不是类,里面可以包含属性、方法、事件 不能包含字段,委托,不能用访问修饰符

    2)接口只能包含没有实现的方法

    3)实现接口的话,必须实现全部方法

    4)接口不能直接实例化,声明的对象只能使用接口里的方法,不能用子类新增的方法

    5)接口可以实现多个

    public interface IPay
        {
            void Pay();
        }
    

    这样在苹果类实现这个接口,就既可以实现支付功能,又不会影响其他类。

       public class iPhone : BasePhone,  IPay
        {
            /// <summary>
            /// 品牌
            /// </summary>
            /// <returns></returns>
            public override string Brand()
            {
                return "iPhone";
            }
    
            /// <summary>
            /// 系统
            /// </summary>
            /// <returns></returns>
            public override string System()
            {
                return "IOS";
            }
    
            /// <summary>
            /// 打电话
            /// </summary>
            public override void Call()
            {
                Console.WriteLine("User{0} {1} {2} Call", this.GetType().Name, this.Brand(), this.System());
            }
    
            /// <summary>
            /// 拍照
            /// </summary>
            public override void Photo()
            {
                Console.WriteLine("User{0} {1} {2} Call", this.GetType().Name, this.Brand(), this.System());
            }
    
    
            public override void Do<T>()
            {
    
            }
    
           
            public void Pay()
            {
                throw new NotImplementedException();
            }
        } 

    说了这么多。那么什么时候用抽象类,什么时候用接口呢

    抽象是模板化,减少一定的代码量;

    接口是功能化,增加一定的灵活性;

    用经典的话说,就是is a,和has a 的关系。

    抽象类本质还是一个类,就好比上面举的例子,BasePhone这个类他的本质还是是一份手机,只不过是把手机一些共有的性能给抽象出来一个类。

    在比如IPay这个接口,它只是为了手机拥有这个功能而存在的,但不是所有的手机都拥有了这个功能,所以说只能把支付功能声明为一个接口。

    最后说说重写overwrite(new)  覆写override 重载overload(方法) 

    在这里就不细说了,直接通过代码是讲述。

    声明一个父类:有普通方法,虚方法,抽象方法,然后子类继承,

    #region abstract
        public abstract class ParentClass
        {
            /// <summary>
            /// CommonMethod
            /// </summary>
            public void CommonMethod()
            {
                Console.WriteLine("ParentClass CommonMethod");
            }
    
            /// <summary>
            /// virtual  虚方法  必须包含实现 但是可以被重载
            /// </summary>
            public virtual void VirtualMethod()
            {
                Console.WriteLine("ParentClass VirtualMethod");
            }
    
            public abstract void AbstractMethod();
        }
    
        public class ChildClass : ParentClass
        {
            /// <summary>
            /// new 隐藏
            /// </summary>
            public new void CommonMethod()
            {
                Console.WriteLine("ChildClass CommonMethod");
            }
            /// <summary>
            /// virtual 可以被覆写
            /// </summary>
            /// <param name="obj"></param>
            /// <returns></returns>
            public override void VirtualMethod()
            {
                Console.WriteLine("ChildClass VirtualMethod");
                base.VirtualMethod();
            }
    
            public override void AbstractMethod()
            {
                Console.WriteLine("ChildClass AbstractMethod");
            }
        }
    
        
        #endregion abstract
    

     通过控制台程序看效果。 

    class Program{
     static void Main(string[] args)
            {
       Console.WriteLine("*******************************************");
                         Console.WriteLine("*******************************************");
                Console.WriteLine("*******************************************");
                ParentClass instance = new ChildClass();
                Console.WriteLine("下面是instance.CommonMethod()");
                instance.CommonMethod();
                Console.WriteLine("下面是instance.VirtualMethod()");
                instance.VirtualMethod();
                Console.WriteLine("下面是instance.AbstractMethod()");
                instance.AbstractMethod();
    }
    
    }        
    

      

    可以看出普通方法,是调用父类的方法,虚方法和抽象方法都是调用子类的,其实不难理解,因为虚方法和抽象方法都被子类给override(覆写)了。

    那什么是重载呢,重载就是方法名相同,参数不同

     public new void CommonMethod()
            {
                Console.WriteLine("ChildClass CommonMethod");
            }
    
            public void CommonMethod(string name)
            {
               Console.WriteLine("ChildClass CommonMethod");
            }
           public void CommonMethod(int id)
            {
                Console.WriteLine("ChildClass CommonMethod");
            }
            public void CommonMethod(int id, string name)
            {
                Console.WriteLine("ChildClass CommonMethod");
           }
    

      

  • 相关阅读:
    《Python机器学习及实践:从零开始通往Kaggle竞赛之路》
    CPA专业阶段单科成绩有5年有效期限,即从通过科目考试的第一年算起
    升级gitk后,Error in startup script: unknown color name "lime"
    新三板:精选反馈问题103题(建议收藏)
    jQuery .on
    onload in JavaScript
    The JavaScript this Keyword
    JavaScript method overload
    JavaScript modularity with RequireJS (from spaghetti code to ravioli code)
    Understanding RequireJS for Effective JavaScript Module Loading
  • 原文地址:https://www.cnblogs.com/xima/p/7123981.html
Copyright © 2011-2022 走看看