C# 與物件導向中的多型技術 (Polymorphism)

基礎篇

C# 簡介

開發環境

變數與運算

流程控制

陣列

函數

物件

例外處理

函式庫篇

檔案處理

資料結構

正規表達式

Thread

應用篇

視窗程式

媒體影音

網路程式

遊戲程式

手機程式

資料庫

雲端運算

特殊功能

委派

擴展方法

序列化

LinQ

WPF

網路資源

教學影片

投影片

教學文章

軟體下載

考題解答

101習題

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

以下是我們用 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());
        }
    }
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License