1. 程式人生 > >C# abstract override 修飾符

C# abstract override 修飾符

定義:

abstract 修飾符指示被修改內容的實現已丟失或不完整。 abstract 修飾符可用於類、方法、屬性、索引和事件。 在類宣告中使用 abstract 修飾符以指示某個類僅旨在作為其他類的基類。 標記為 abstract 的成員,或包含在抽象類中的成員,都必須由派生自抽象類的類來實現。

 

功能:

抽象類具有以下功能:

  • 抽象類不能例項化。

  • 抽象類可能包含抽象方法和訪問器。

  • 無法使用 sealed 修飾符來修改抽象類,因為兩個修飾符具有相反的含義。 sealed

     修飾符阻止類被繼承,而 abstract 修飾符要求類被繼承。

  • 派生自抽象類的非抽象類,必須包含全部已繼承的抽象方法和訪問器的實際實現。

在方法或屬性宣告中使用 abstract 修飾符,以指示該方法或屬性不包含實現。

 

抽象方法具有以下功能:

  • 抽象方法是隱式的虛擬方法。

  • 只有抽象類中才允許抽象方法宣告。

  • 由於抽象方法宣告不提供實際的實現,因此沒有方法主體;方法宣告僅以分號結尾,且簽名後沒有大括號 ({ })

  • 通過包含使用 override 修飾符的屬性宣告,可在派生類中重寫抽象繼承屬性 

附:1.在靜態屬性,方法上使用 abstract 修飾符是錯誤的

       2.在抽象方法宣告中使用 static 或 virtual 修飾符是錯誤的

 

例子

在遊戲中特效一般是很常見的,一般特效也會分很多種,比如不同的子彈打擊需要呈現不同的效果

1.建立特效基類

public abstract class Effect : MonoBehaviour {

    private int id;
    public static int Id = 0;
    public abstract int X { get; } //抽象屬性 
    public abstract string IdxString { get; set; } //抽象屬性 
    public abstract char this[int i] { get; } //抽象索引器 

    public abstract void Init(params object[] args);// 抽象方法 

    /// <summary>
    /// 建立特效
    /// </summary>
    /// <param name="efxName"></param>
    /// <param name="args"></param>
    /// <returns></returns>
    public static Effect Create(string eftName, params object[] args) {
        GameObject go = Spawn(eftName);
        Effect eft = go?.GetComponent<Effect>();
        eft?.Init(args);
        return eft;
    }

    public static GameObject Spawn(string efxName) {
        //TODO 獲取特效物件
        //return ObjectPool.instance.GetObjectFromPool(efxName);
        return null;
    }

    public static void UnSpawn(GameObject go) {
        //TODO 回收特效
        //ObjectPool.instance.ReturnObjectToPool(go);
    }
}

2.建立加農炮彈特效子類

public sealed class CannonEft : Effect {

    private string skillId;
    private bool otherTurretHit;
    private int bulletId;
    private float range;
    private int userId;

    private string idxString;
    private int id;
    private int x;

    public override char this[int i] => IdxString[i];

    public override int X {
        get {
            return x;
        }
    }

    public override string IdxString {
        get 
            { return idxString; }
        set 
            { idxString = value; }
    }

    /// <summary>
    /// 初始化
    /// </summary>
    /// <param name="args">引數陣列</param>
    public override void Init(params object[] args) {
        this.skillId = (string)args[1];
        this.otherTurretHit = (bool)args[2];
        this.bulletId = (int)args[3];
        this.range = (float)args[4];
        this.userId = (int)args[5];

        //TODO 呼叫其他的一些操作
        Debug.Log("Effect Init");

        //回收
        this.Invoke("Recycle", 1f);
    }

    public void DebugLog() {
        print("CannonEft func");
    }

    private void Recycle() {
        Effect.UnSpawn(this.gameObject);
    }
}

3.測試指令碼

    private string skillId="skill_Cannon";
    private bool otherTurretHit = false;
    private int bulletId=0;
    private float range=5;
    private int userId=1001;
   
    void Start () {
        CannonEft eft= (CannonEft)Effect.Create("特效名稱", skillId, otherTurretHit, bulletId, range, userId);
        eft.DebugLog();
	}

解析:

在基類Effect中定義

    public abstract int X { get; } //抽象屬性 
    public abstract string IdxString { get; set; } //抽象屬性 
    public abstract char this[int i] { get; } //抽象索引器 

    public abstract void Init(params object[] args);// 抽象方法 

必須在子類CannonEft中override重寫,不然報錯

 

呼叫時很簡單:Effect.Create("特效名稱", skillId, otherTurretHit, bulletId, range, userId)

引數傳遞是object[]