物件導向的多型機制,是指當兩個以上的類別繼承同一種父類別時,我們可以用父類別型態容納子類別的物件,真正進行函數呼叫時會呼叫到子類別的函數,此種特性稱之為多型。

以下是我們用 C# 實作的一個多型範例,在範例中,我們宣告了一個形狀類別,該類別具有一個 area() 函數可以計算該形狀的面積,然後我們又宣告了兩個子類別 Rectangle (矩形) 與 Circle (圓形)。我們將兩者放入到 shapes 陣列中,以便展示多型技巧,用父類別容器呼叫子類別的實體。

範例:形狀、矩形與圓形

using System;
class Shape
{
    public virtual double area() { return 0.0; }
    public static void Main(string[] args)
    {
        Rectangle r = new Rectangle(5.0, 8.0);
        Console.WriteLine("r.area() = " + r.area());
        Circle c = new Circle(3.0);
        Console.WriteLine("c.area() = " + c.area());
        Shape[] shapes = { r, c };
        for (int i = 0; i < shapes.Length; i++)
            Console.WriteLine("shapes[" + i + "].area()=" + shapes[i].area());
    }
}
class Rectangle : Shape
{
    double width, height;
    public Rectangle(double w, double h)
    {
        width = w;
        height = h;
    }
    public override double area()
    {
        return width * height;
    }
}
class Circle : Shape
{
    double r;
    public Circle(double r)
    {
        this.r = r;
    }
    public override double area()
    {
        return 3.1416 * r * r;
    }
}
	

執行結果

r.area() = 40
c.area() = 28.2744
shapes[0].area()=40
shapes[1].area()=28.2744
	

範例:使用抽象父型態

using System;
class ShapeTest
{
    public static void Main(string[] args)
    {
        Rectangle r = new Rectangle(5.0, 8.0);
        Console.WriteLine("r.area() = " + r.area());
        Circle c = new Circle(3.0);
        Console.WriteLine("c.area() = " + c.area());
        Shape[] shapes = { r, c };
        for (int i = 0; i < shapes.Length; i++)
            Console.WriteLine("shapes[" + i + "].area()=" + shapes[i].area());
    }
}
abstract class Shape
{
    public abstract double area();
}
class Rectangle : Shape
{
    double width, height;
    public Rectangle(double w, double h)
    {
        width = w;
        height = h;
    }
    public override double area()
    {
        return width * height;
    }
}
class Circle : Shape
{
    double r;
    public Circle(double r)
    {
        this.r = r;
    }
    public override double area()
    {
        return 3.1416 * r * r;
    }
}
	

執行結果:

r.area() = 40
c.area() = 28.2744
shapes[0].area()=40
shapes[1].area()=28.2744
	

範例:使用介面

using System;
class ShapeTest
{
    public static void Main(string[] args)
    {
        Rectangle r = new Rectangle(5.0, 8.0);
        Console.WriteLine("r.area() = " + r.area());
        Circle c = new Circle(3.0);
        Console.WriteLine("c.area() = " + c.area());
        Shape[] shapes = { r, c };
        for (int i = 0; i < shapes.Length; i++)
            Console.WriteLine("shapes[" + i + "].area()=" + shapes[i].area());
    }
}
interface Shape
{
    double area();
}
class Rectangle : Shape
{
    double width, height;
    public Rectangle(double w, double h)
    {
        width = w;
        height = h;
    }
    public double area()
    {
        return width * height;
    }
}
class Circle : Shape
{
    double r;
    public Circle(double r)
    {
        this.r = r;
    }
    public double area()
    {
        return 3.1416 * r * r;
    }
}
	

執行結果:

r.area() = 40
c.area() = 28.2744
shapes[0].area()=40
shapes[1].area()=28.2744
	

範例:較完整複雜的版本

using System;
class Shape
{
    public double thick = 0.0;
    public virtual double area() { return 0.0; }
    public double volume()
    {
        return area() * thick;
    }
    public override String ToString()
    {
        return "Shape: thick=" + thick+" area="+area()+" volume="+volume();
    }
}
class Rectangle : Shape
{
    double width, height;
    public Rectangle(double w, double h)
    {
        width = w;
        height = h;
        thick = 2.0;
    }
    public override String ToString()
    {
        return base.ToString()+" Rectangle:width=" + width + " height=" + height;
    }
    public override double area()
    {
        return width * height;
    }
}
class Circle : Shape
{
    double r;
    public Circle(double r)
    {
        this.r = r;
        thick = 3.0;
    }
    public override String ToString()
    {
        return base.ToString() + " Circle:r=" + r + " thick=" + thick;
    }
    public override double area()
    {
        return 3.1416 * r * r;
    }
}
class Test
{
    public static void Main(string[] args)
    {
        Shape s = new Shape();
        Console.WriteLine("s.area() = " + s.area());
        Rectangle r = new Rectangle(5.0, 8.0);
        Console.WriteLine("r.area() = " + r.area());
        Console.WriteLine("r.volume() = " + r.volume());
        Circle c = new Circle(2);
        Console.WriteLine("c.area() = " + c.area());
        Console.WriteLine("c.volume() = " + c.volume());
        c.thick = 5;
        Console.WriteLine("c.volume() = " + c.volume());
        Shape[] array = new Shape[] { s, r, c, r };
        foreach (Shape o in array)
        {
//            Console.WriteLine("o.area()=" + o.area() +" o.volume()="+o.volume());
            Console.WriteLine(o.ToString());
        }
    }
}
	

文章轉載:陳鍾誠 (2010年10月19日),(網頁標題) C# 與物件導向中的多型技術 (Polymorphism),(網站標題) 免費電子書:C# 程式設計,2010年10月19日,取自 http://cs0.wikidot.com/polymorphism ,網頁修改第 3 版。

arrow
arrow

    Johnson峰 發表在 痞客邦 留言(0) 人氣()