C#中抽象類和接口

   下面是我作的測試:asp.net

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace ClassDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //BaseClass bc = new BaseClass();
            //bc.sayHello();

            //DerivedClass dc = new DerivedClass();
            //dc.sayHello();

            //BaseClass bc2 = new DerivedClass();
            //bc2.sayHello();

            //Test test = new Test();
            //test.sayHello();

            //BaseClass bc = new DerivedClass2();
            //bc.sayHello();

            //索引器
            //IndexDemo id = new IndexDemo();
            //id[0] = "chen";
            //id[1] = "yu";
            //id[2] = "ming";
            //Console.WriteLine("{0}{1}{2}", id[0], id[1], id[2]);

            //抽象類和接口
            //ITest it = new ITest(); //error:沒法建立抽象類或接口的實例
            //ATest at = new ATest(); //error:沒法建立抽象類或接口的實例
            Test t = new Test();
            t.sayHello();
            //t.X = 100;
            //Console.WriteLine(t.X);
            Test2 t2 = new Test2();
            t2.sayHello();
            Console.WriteLine(t2.add());
            Console.WriteLine(t2.add2());
            t2.x = 10;
            Console.WriteLine(t2.x);
        }

        //嵌套類
        private class Test //類裏面定義類,這裏的類是能夠有修飾符的private
        {
            public void sayHello()
            {
                Console.WriteLine("ClassTest sayHello");
            }
        }
    }

    //抽象類與接口
    public interface ITest
    {
        //public int x; //error:接口不能包含字段
        void sayHello(); //error:不能有如public、abstract的修飾符
        //int add() { return 1 + 2; }//error:接口成員不能有定義
        int X { get; set; }
    }

    public class Test : ITest
    {
        private int _x;
        public void sayHello()
        {
            Console.WriteLine("Test sayHello");
        }
        public int X { get { return _x; } set { _x = value; } }
    }

    abstract class ATest
    {
        public int x;
        public abstract void sayHello();
        public int add() { return 1 + 2; }
        public virtual int add2() { return 2 + 3; }
    }

    class Test2 : ATest
    {
        public override void sayHello()//重寫virtual、abstract必須經過override
        {
            Console.WriteLine("Test2 sayHello");
        }

        public override int add2() { return 3 + 4; }
    }

    public class BaseClass //命名空間中定義的元素沒法顯式聲明爲private、protected 或protected internal但能夠是public
    {
        public BaseClass()
        {
            Console.WriteLine("BaseClass");
        }
        public BaseClass(string str)
        {
            Console.WriteLine("BaseClass " + str);
        }
        public virtual void sayHello()
        {
            Console.WriteLine("BaseClass sayHello");
        }
    }

    class DerivedClass : BaseClass
    {
        public DerivedClass()
        {
            Console.WriteLine("DerivedClass");
        }

        public new void sayHello()//有意掩藏基類的方法 new
        {
            Console.WriteLine("DerivedClass sayHello");
        }

        public void drawLine(params Point[] pt)
        {
 
        }
    }

    class Point
    {
        private int _x;
        public int X { get { return _x; } set { _x = value;} }
        private int _y;
        public int Y { get { return _y; } set { _y = value; } }
    }

    //void sayHello()//error:命名空間並不直接包含諸如字段或方法之類的成員
    //{   
    //}

    class DerivedClass2 : BaseClass
    {
        public override void sayHello()
        {
            Console.WriteLine("DerivedClass2 sayHello");
        }
    }

    class IndexDemo
    {
        protected ArrayList al = new ArrayList();

        public object this[int index]
        {
            get
            {
                if (index > -1 && index < al.Count)
                {
                    return al[index];
                }
                else
                {
                    return null;
                }
            }
            set
            {
                if (index > -1 && index < al.Count)
                {
                    al[index] = value;
                }
                else if (index == al.Count)
                {
                    al.Add(value);
                }
                else
                {
                   
                }
            }
        }
    }
}

  以上測試得出如下幾個結論:ide

  一、抽象類與接口均不能實例化。函數

  二、接口不能包含字段。oop

  三、包含的方法只能有聲明,不能定義,且不能有如public、abstract的修飾符。測試

  四、抽象類與通常的類的的區別是:它不能實例化。this

  

  1、抽象類:
      抽象類是特殊的類,只是不能被實例化;除此之外,具備類的其餘特性;重要的是抽象類能夠包括抽象方法,這是普通類所不能的。抽象方法只能聲明於抽象類中,且不包含任何實現,派生類必須覆蓋它們。另外,抽象類能夠派生自一個抽象類,能夠覆蓋基類的抽象方法也能夠不覆蓋,若是不覆蓋,則其派生類必須覆蓋它們。

      2、接口:
      接口是引用類型的,相似於類,和抽象類的類似之處有三點:
      1. 不能實例化;
      2. 包含未實現的方法聲明;
      3. 派生類必須實現未實現的方法,抽象類是抽象方法,接口則是全部成員(不只是方法包括其餘成員);
      另外,接口有以下特性:
      接口除了能夠包含方法以外,還能夠包含屬性、索引器、事件,並且這些成員都被定義爲公有的。除此以外,不能包含任何其餘的成員,例如:常量、域、構造函數、析構函數、靜態成員。一個類能夠直接繼承多個接口,但只能直接繼承一個類(包括抽象類)。

      3、抽象類和接口的區別:
      1. 類是對對象的抽象,能夠把抽象類理解爲把類看成對象,抽象成的類叫作抽象類.而接口只是一個行爲的規範或規定,微軟的自定義接口老是後帶able字段,證實其是表述一類類「我能作。。。」。抽象類更多的是定義在一系列緊密相關的類間,而接口大多數是關係疏鬆但都實現某一功能的類中;
      2. 接口基本上不具有繼承的任何具體特色,它僅僅承諾了可以調用的方法;
      3. 一個類一次能夠實現若干個接口,可是隻能擴展一個父類;
      4. 接口能夠用於支持回調,而繼承並不具有這個特色;
      5. 抽象類不能被密封;
      6. 抽象類實現的具體方法默認爲虛的,但實現接口的類中的接口方法卻默認爲非虛的,固然您也能夠聲明爲虛的;
      7.(接口)與非抽象類相似,抽象類也必須爲在該類的基類列表中列出的接口的全部成員提供它本身的實現。可是,容許抽象類將接口方法映射到抽象方法上;
      8. 抽象類實現了oop中的一個原則,把可變的與不可變的分離。抽象類和接口就是定義爲不可變的,而把可變的座位子類去實現;
      9. 好的接口定義應該是具備專注功能性的,而不是多功能的,不然形成接口污染。若是一個類只是實現了這個接口的中一個功能,而不得不去實現接口中的其餘方法,就叫接口污染;
     10. 儘可能避免使用繼承來實現組建功能,而是使用黑箱複用,即對象組合。由於繼承的層次增多,形成最直接的後果就是當你調用這個類羣中某一類,就必須把他們所有加載到棧中!後果可想而知。(結合堆棧原理理解)。同時,有心的朋友能夠留意到微軟在構建一個類時,不少時候用到了對象組合的方法。好比 asp.net中,Page類,有Server Request等屬性,但其實他們都是某個類的對象。使用Page類的這個對象來調用另外的類的方法和屬性,這個是很是基本的一個設計原則;
     11.若是抽象類實現接口,則能夠把接口中方法映射到抽象類中做爲抽象方法而沒必要實現,而在抽象類的子類中實現接口中方法。 

      4、抽象類和接口的使用:
      1. 若是預計要建立組件的多個版本,則建立抽象類。抽象類提供簡單的方法來控制組件版本;
      2.若是建立的功能將在大範圍的全異對象間使用,則使用接口。若是要設計小而簡練的功能塊,則使用接口;
      3.若是要設計大的功能單元,則使用抽象類。若是要在組件的全部實現間提供通用的已實現功能,則使用抽象類; 
      4.抽象類主要用於關係密切的對象;而接口適合爲不相關的類提供通用功能。

spa

相關文章
相關標籤/搜索