DEV Community

Cover image for C# - Abstract modifier
FakeStandard
FakeStandard

Posted on • Edited on

2

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.


Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay