1. 程式人生 > >C#中抽象類(abstract)的例項引用

C#中抽象類(abstract)的例項引用

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace AppTest
{
    class Demo_abstract
    {
        static void Main(string[] args)
        {
            double len = 2.5;
            double wid = 3.0;
            double rad = 4.1;
            Rectangle aRect = new Rectangle();
            aRect.length = len;
            aRect.width = wid;
            Circle aCirc = new Circle(rad);
            Console.WriteLine("Area of Rect is:{0}", aRect.Area());
            Console.WriteLine("Area of Circ is:{0}", aCirc.Area());

            //體現 abstract 的優勢,不用的例項獲取不同的功能
            //結果與 Rectangle例項的一樣
            Shape shape = new Rectangle(len, wid);
Console.WriteLine("Area of shape is:{0}", shape.Area());

            Thread.Sleep(3 * 1000); //暫停3秒看結果
        }
    }

    //圖形
    abstract class Shape                //抽象基類,不可例項化
    {
        public const double pi = 3.14;    //常量
        protected double x, y;            //私有,可繼承變數

        public Shape()                    //預設建構函式
        {
            x = y = 0;
        }
        public Shape(double x, double y)    //帶引數建構函式
        {
            this.x = x;
            this.y = y;
        }
        public abstract double Area();    //抽象方法,需過載
    }

    //方形
    class Rectangle : Shape
    {
        public Rectangle() : base() { }
        public Rectangle(double x, double y) : base(x, y) { }//使用基類建構函式
        public override double Area()    //函式過載
        {
            return (x * y);
        }
        public double length    //屬性:矩形長度
        {
            get
            {
                return x;
            }
            set
            {
                if (value > 0) { x = value; }
            }
        }
        public double width        //屬性:矩形寬度
        {
            get
            {
                return y;
            }
            set
            {
                if (value > 0) { y = value; }
            }
        }

    }

    //橢圓
    class Ellipse : Shape
    {
        public Ellipse(double x, double y) : base(x, y) { }//使用基類Shape的建構函式
        public override double Area()    //函式過載
        {
            return pi * x * y;
        }
    }

    //圓形
    class Circle : Ellipse
    {
        public Circle(double r) : base(r, 0) { }    //使用基類Ellipse的建構函式
        public override double Area()    //函式過載
        {
            return pi * x * x;
        }
    }

}
/*
什麼是介面?
介面是包含一組虛方法的抽象型別,其中每一種方法都有其名稱、引數和返回值。介面方法不能包含任何實現,CLR允許介面可以包含事件、屬性、索引器、靜態方法、靜態欄位、靜態建構函式以及常數。但是注意:C#中不能包含任何靜態成員。一個類可以實現多個介面,當一個類繼承某個介面時,它不僅要實現該介面定義的所有方法,還要實現該介面從其他介面中繼承的所有方法。

什麼是抽象類?
抽象類提供多個派生類共享基類的公共定義,它既可以提供抽象方法,也可以提供非抽象方法。抽象類不能例項化,必須通過繼承由派生類實現其抽象方法,因此對抽象類不能使用new關鍵字,也不能被密封。如果派生類沒有實現所有的抽象方法,則該派生類也必須宣告為抽象類。另外,實現抽象方法由overriding方法來實現。

相同點和不同點

相同點
都不能被直接例項化,都可以通過繼承實現其抽象方法。
都是面向抽象程式設計的技術基礎,實現了諸多的設計模式。

不同點
介面支援多繼承;抽象類不能實現多繼承。
介面只能定義抽象規則;抽象類既可以定義規則,還可能提供已實現的成員。
介面是一組行為規範;抽象類是一個不完全的類,著重族的概念。
介面可以用於支援回撥;抽象類不能實現回撥,因為繼承不支援。
介面只包含方法、屬性、索引器、事件的簽名,但不能定義欄位和包含實現的方法;抽象類可以定義欄位、屬性、包含有實現的方法。
介面可以作用於值型別和引用型別;抽象類只能作用於引用型別。例如,Struct就可以繼承介面,而不能繼承類。

規則與場合

請記住,面向物件思想的一個最重要的原則就是:面向介面程式設計。
藉助介面和抽象類,23個設計模式中的很多思想被巧妙的實現了,我認為其精髓簡單說來就是:面向抽象程式設計。
抽象類應主要用於關係密切的物件,而介面最適合為不相關的類提供通用功能。
介面著重於CAN-DO關係型別,而抽象類則偏重於IS-A式的關係;
介面多定義物件的行為;抽象類多定義物件的屬性;
介面定義可以使用public、protected、internal 和private修飾符,但是幾乎所有的介面都定義為public,原因就不必多說了。
“介面不變”,是應該考慮的重要因素。所以,在由介面增加擴充套件時,應該增加新的介面,而不能更改現有介面。
儘量將介面設計成功能單一的功能塊,以.NET Framework為例,IDisposable、IDisposable、IComparable、IEquatable、IEnumerable等都只包含一個公共方法。
介面名稱前面的大寫字母“I”是一個約定,正如欄位名以下劃線開頭一樣,請堅持這些原則。
在介面中,所有的方法都預設為public。
如果預計會出現版本問題,可以建立“抽象類”。例如,建立了狗(Dog)、雞(Chicken)和鴨(Duck),那麼應該考慮抽象出動物(Animal)來應對以後可能出現風馬牛的事情。而向介面中新增新成員則會強制要求修改所有派生類,並重新編譯,所以版本式的問題最好以抽象類來實現。
從抽象類派生的非抽象類必須包括繼承的所有抽象方法和抽象訪問器的實實現。
對抽象類不能使用new關鍵字,也不能被密封,原因是抽象類不能被例項化。
在抽象方法宣告中不能使用 static 或 virtual 修飾符。
*
*
*
*
*
* 另外一個例子

1. 定義抽象類

    public abstract class Animal
    {
        protected string _name;

        //宣告抽象屬性
        public abstract string Name
        {
            get;
        }

        //宣告抽象方法
        public abstract void Show();

        //實現一般方法
        public void MakeVoice()
        {
            Console.WriteLine("All animals can make voice!");
        }
    }

2. 定義介面

    public interface IAction
    {
        //定義公共方法標籤
        void Move();
    }

3. 實現抽象類和介面


    public class Duck : Animal, IAction
    {
        public Duck(string name)
        {
            _name = name;
        }

        //過載抽象方法
        public override void Show()
        {
            Console.WriteLine(_name + " is showing for you.");
        }

        //過載抽象屬性
        public override string Name
        {
            get { return _name;}
        }

        //實現介面方法
        public void Move()
        {
            Console.WriteLine("Duck also can swim.");
        }

    }

    public class Dog : Animal, IAction
    {
        public Dog(string name)
        {
            _name = name;
        }

        public override void Show()
        {
            Console.WriteLine(_name + " is showing for you.");
        }

        public override string Name
        {
            get { return _name; }
        }

        public void Move()
        {
            Console.WriteLine(_name + " also can run.");
        }

    }

4. 客戶端實現


    public class TestAnmial
    {
        public static void Main(string [] args)
        {
            Animal duck = new Duck("Duck");
            duck.MakeVoice();
            duck.Show();

            Animal dog = new Dog("Dog");
            dog.MakeVoice();
            dog.Show();

            IAction dogAction = new Dog("A big dog");
            dogAction.Move();
        }
    }