簡體   English   中英

繼承一個接口,實現部分方法,讓派生類實現其余的

[英]inherit an interface, implement part of the methods, let a derived class implement the rest

定義以下C#接口:

public interface IShape
{
    int NumberOfLineSegments {get;}
    int Area {get;}
}

接下來,我想定義幾個矩形類:Trapezoid,square等。 所有這些類的Area()屬性都不同,但NumberOfLineSegments()總是返回4.因此,我想要一個名為Rectangle(或IRectangle)的'臨時'類或接口,它看起來像:

public Rectangle : IShape
{
    public int NumberOfLineSegments{get{return 4;}}
}

我希望Rectangle只實現NumberOfLineSegment(),並將其留給派生類來實現其余的:

public Square : Rectangle 
{
    public int Area() {get{return length*height;}
}

但是,由於IShape是一個接口,Rectangle類也必須實現Area(),它不知道如何實現。因此,我似乎被卡住了,要么為Rectangle定義'dummy'Fare()方法,要么完全使用繼承權。

有沒有辦法規避這個? 我通過c#和StackOverflow在Richter的clr中廣泛閱讀。 提前致謝!

Rectangle類應該是abstract並將Area()方法定義為abstract。

public interface IShape
{
    int NumberOfLineSegments {get;}
    float Area{get;}
}

public abstract class RectangleBase : IShape
{
    public int NumberOfLineSegments { get { return 4; } }

    public abstract float Area { get; }
}

public sealed class Square : RectangleBase
{
    public override fload Area() { get { return length*height; }
}

如果你需要Rectangle實例:

public sealed class Rectangle : ReectangleBase
{
    public int NumberOfLineSegments { get { return 4; } }

    public float Area { get { throw new NotImplementedException(); } }
}

有兩種選擇。

  1. 使實現虛擬並為空(或拋出NotImplementedException ),因此在派生之前它默認不執行任何操作。
  2. 使基類抽象化並為要強制鏈的接口方法創建抽象簽名。

編號2是優選的,因為它迫使派生類實現該方法,而在數1派生類不會被強迫重載基礎虛擬方法。

抽象方法可以成功地滿足接口定義,因為編譯器將知道抽象類本身不能被實例化,並且任何派生類都被迫實現抽象方法。

也就是說,如果存在對特定類型沒有意義的接口成員,則通常是分解接口的指示符:

public interface IShape : ICalculateArea, IHaveLineSegments
{
}

public interface ICalculateArea
{
    float Area { get; }
}

public interface IHaveLineSegments
{
    int NumberOfLineSegments { get; }
}

class Rectangle : IHaveLineSegments
{
    public int NumberOfLineSegments { get; private set; }
}

class Square : Rectangle, IShape
{
    public float Area { get; private set; }
}

將方法定義為抽象。

public abstract float Area{get;}

使用實現接口的抽象類:

public abstract class Rectangle : IShape {
    public int NumberOfLineSegments { get { return 4; } }
    public abstract float Area { get; }
}

然后,您的特定矩形類只是從Rectangle抽象類繼承。

這沒關系? 強制派生類中的實現。

public abstract class Rectangle : IShape
{
    NumberOfLineSegments{get{return 4;}}
    abstract float Area { get; }
}

我個人更喜歡@sll的解決方案(以及其他基本相同的解決方案),但是對於記錄,還有一種方法:

public interface IShape
{
    int NumberOfLineSegments {get;}
    float Area{get;}
}

public class Rectangle
{
    public int NumberOfLineSegments { get { return 4; } }
}

public sealed class Square : Rectangle, IShape
{
    public float Area() { get { return length*height; }
}

通過這種方式,您可以節省abstract類,但需要定義一個剛性超類(因此您無法為Square提供不同的超類)。

請注意,盡管Rectangle沒有實現IShape ,但這仍然有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM