DEV Community

Cover image for C# - Abstract modifier
FakeStandard
FakeStandard

Posted on • Edited on

C# - Abstract modifier

使用 abstract 修飾詞的項目代表它具有不完整的實作,abstract 修飾詞可以與類別、 屬性、方法、索引子和事件搭配使用,例如標記為 abstract 的類別表示該類別作為其他類別的父類別,它自己不提供實作,而是由非抽象的子類別來實作

abstract class Shape
{
    public abstract int GetArea();
}

class Square : Shape
{
    private int side;

    public Square(int side)
    {
        this.side = side;
    }

    public override int GetArea() => side * side;
}
Enter fullscreen mode Exit fullscreen mode

繼承抽象類別的子類別必須包含所有抽象類別的成員實作,例如方法、存取子等等,子類別提供實作時使用 override 修飾詞來覆寫具有抽象修飾詞的項目。以下為例,S 繼承 F 類別卻未提供 override 修飾詞直接實作 Foo 方法

abstract class F
{
    protected abstract void Foo();
}

class S : F
{
    protected void Foo() { }
}
Enter fullscreen mode Exit fullscreen mode

此時編譯器會回報出必需實作 F 類別的 Foo 方法

pic-014

abstractsealed 修飾詞的意義相反,抽象必須被繼承以實作,密封則是防止被繼承,故兩者不能同時使用;也不可將類別同時定義成靜態和抽象,兩者只能擇一

pic-011

不可在抽象方法中使用 virtual 修飾詞,否則編譯器會回報錯誤

pic-012

也不可在抽象方法中使用 static 修飾詞,編譯器會回報方法不可宣告為抽象

pic-013

在抽象類別中才可宣告抽象方法或屬性,但抽象類別中可以宣告非抽象的方法或屬性,如果在非抽象類別中定義抽象方法,編譯器會回報錯誤

pic-010

當抽象類別繼承介面時,必須提供所有介面的實作,實作介面時可將方法定義為抽象或非抽象

// 將實作介面方法定義為抽象,子類別繼承時依然須實作方法
interface IShape
{
    int GetArea();
}

abstract class Shape : IShape
{
    public abstract int GetArea();
}

class Square : Shape
{
    private int side;

    public Square(int side)
    {
        this.side = side;
    }

    public override int GetArea() => side * side;
}

// 或者將實作介面方法定義為非抽象,直接在抽象類別中實作方法
interface IShape
{
    int GetArea();
}

abstract class Shape : IShape
{
    protected int side = 10;

    public int GetArea() => side * side;
}

class Square : Shape
{
    public Square(int side)
    {
        this.side = side;
    }
}
Enter fullscreen mode Exit fullscreen mode

嘗試使用抽象類別、屬性和方法,並在子類別提供實作

/// <summary>
/// abstract class
/// </summary>
abstract class Shape
{
    protected int x = 10;
    protected int y = 10;

    // abstract properties
    public abstract int X { get; }
    public abstract int Y { get; }

    // abstract method
    public abstract int GetArea();
}

class Square : Shape
{
    public Square() { }
    public Square(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    // override properties
    public override int X => x + 10;
    public override int Y => y + 10;

    // override method
    public override int GetArea() => X * Y;
}
Enter fullscreen mode Exit fullscreen mode

還有關於抽象類別很重要的一點,抽象類別不可被實體化,因為它必須被子類別繼承,再由子類別實體化後提供實作,故當嘗試將抽象類別實體化時,編譯器會會引發錯誤

pic-009

Reference

abstract


Thanks for reading the article 🌷 🌻 🌼

If you like it, please don't hesitate to click heart button ❤️
or follow my GitHub ⭐ I'd appreciate it.


Top comments (0)