C#中的类和基类继承

10

我有一个C#的类,像这样:

public class BarChart
{
    public BarData BarChartData;
    public BarStyle BarChartStyle;

    public BarChart(BarData data, BarStyle style)
    {
        this.BarChartData = data;
        this.BarChartStyle = style;
    }

    string _uniqueName;
    public string UniqueName
    {
        get { return this._uniqueName; }
        set { this._uniqueName = value; }
    }
    string _rowNumber;
    public string RowNumber
    {
        get { return this._rowNumber; }
        set { this._rowNumber = value; }
    }

我想创建一个名为Chart的类,它将具有BarChart类拥有的所有属性。例如:

Chart someChart = new Chart(BarChart);
string name = someChart.UniqueName

我对C#相对较新,继承的概念对我来说有些陌生。最终我将拥有多个不同的图表类型,如LineChart、BarChart等,但我也希望能够像这样移动和排序它们:

List<Chart> groupedCharts = listOfCharts
.GroupBy(u => u.RowNumber)
.Select(grp => grp.ToList())
.ToList();

所以将它们放入通用的Chart类中,以便与LINQ轻松使用。

我该如何设置它?


@DarrenYoung 可能不是全部,我猜只有共享的。对于我的使用,目前实际上只需要共享 RowNumber。 - konrad
3个回答

17
创建一个抽象的图表类:
abstract class Chart
{
    // Shared properties
}

然后继承它:

class BarChart : Chart
{
    // Bar chart properties
}

那么您可以这样创建:

Chart someChart = new BarChart();

1
你为什么认为它需要抽象化? - David Pine
3
没有指定图表类型(折线图、柱状图、饼图),对我来说它看起来确实很抽象,尽管这与问题并没有直接关联。 - spender
1
@DavidPine 我想我总是把一个基类作为抽象类开始,直到它需要变得具体(当然这总是在设计阶段 -- 你永远不会想在生产后进行这种更改)。 - rory.ap
2
我改变了我的答案,我更喜欢接口而不是抽象类。这是我的个人意见。 - David Pine
2
@DavidPine 我个人不喜欢选择接口,因为它不允许字段,如果你在接口中指定属性,它会强制你“实现”它们,而大多数情况下这会违反DRY原则。 - Marco Fatica
显示剩余3条评论

10

你需要创建一个类似这样的界面:

    public interface IChart
    {
        string UniqueName { get; set; }

        string RowNumber { get; set; }
    }

然后让其他类继承基类,如下所示...

    public class BarChart : IChart
    {
        public BarData BarChartData { get; private set; }
        public BarStyle BarChartStyle { get; private set; }

        // Other custom members you desire for your bad chart implementation

        public BarChart(BarData data, BarStyle style)
        {
            BarChartData = data;
            BarChartStyle = style;
        }
    }

MSDN的示例可以在这里找到。个人建议在确定所有图表确实具有可封装的共同逻辑之前,避免使用抽象类。现在没有超设计的理由,只需使用接口即可。

希望这对你有所帮助!


小问题... 你演示的是"继承/实现一个接口",而不是"继承基类"。 - spender

5

您可能不希望实例化基本的Chart类,因为它的功能是模糊不清的,所以您需要将其设置为抽象类。

public abstract class Chart
{
    // Public properties common to all charts
    public ChartData data;
    public ChartStyle style;
    public string RowNumber { get; set; }
    public string UniqueName { get; set; }

    // A common method    
    public void AddDataPoint () {}

    // A method all charts have that may change between different types of charts
    public virtual void DrawChart () {}

    // Constructor
    public Chart (ChartData cd, ChartStyle cs)
    {
        data = cd;
        style = cs;
    }

    // Protected method (like a private method, but gets inherited)
    protected void Finalize () {}
}

您希望继承类的代码如下所示:
```html

您需要的内容:

```
public class BarChart : Chart
{
    // BarChart exclusive properties

    // A method all charts have that BarCharts implements differently
    public override void DrawChart () {}

    // Constructor that calls the base constructor
    public BarChart (ChartData cd, ChartStyle cs) : base (cd, cs)
    {

    }
}

在方法中,您需要确保使用virtualoverride关键字,以便基类方法的调用被子类方法覆盖。

抽象类 vs 接口

与接口不同,抽象类允许您定义其中的方法。接口中的方法都只是签名。在抽象类中,您还可以具有仅定义了其签名的抽象方法。但是,抽象类与普通类一样在继承方面工作;您只能从一个类继承。您可以从尽可能多个接口继承。如果您想要BarChart继承Chart和接口IComparable,则应该先声明抽象类,如public class BarChart : Chart, IComparable


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接