【问题标题】:Abstract Classes and ReadOnly Properties抽象类和只读属性
【发布时间】:2011-06-08 01:13:36
【问题描述】:

让我们有三个类;

Line
PoliLine
SuperPoliLine

为所有这三个类定义了一个Distance

但只有Line一个Distance可以设置。

有没有可能建立一个通用的abstract(MustInherit)类Segment,有一个Distance作为(abstract + ? 只读) 成员?

VB.NET 的问题,但也欢迎 C# 回答。


业务背景

想象一辆公共汽车。它有很多 Stations、MainStations 和 2 个TerminalStations。所以 Line 在 2 个 Station 之间,PoliLine 在 2 个 MainStations 之间,SuperPoliLine 在 2 个 TerminalStation 之间。所有“线”都是“线段”,但只能定义2个车站之间的距离A->B - Line

【问题讨论】:

  • 你希望 Segment 类继承自 Line?
  • @Andrew Bezzub:是的。我将 Line 更改为 Segment :) 让我更“现实”。所以 Line 应该继承自 Segment
  • 就我所知,折线不是直线。由于没有给出“是”关系,因此折线应该是线的组合,但不能向下转换为线,甚至不能转换为线段。也许在这里声明接口会更合适。在这种情况下,superpolyline 没有多大意义,因为多条折线也是一条折线
  • Serhio,你的设计不连贯。

标签: c# .net vb.net oop


【解决方案1】:

您不能同时覆盖和重新声明(以添加集合) - 但您可以这样做:

基类:

protected virtual int FooImpl { get; set; } // or abstract
public int Foo { get { return FooImpl; } }

派生类:

new public int Foo {
    get { return FooImpl; }
    set { FooImpl = value; }
}

// your implementation here... 
protected override FooImpl { get { ... } set { ... } }

现在您还可以根据需要覆盖 FooImpl。

【讨论】:

  • 用户应该能够设置到PoliLine(派生类)的距离,但是到Line
  • 由于PolyLine 不能替代Line,因此不应从它派生。也许给他们一个共同的基类。
  • @CodeInChaos:可以。如果需要,可以将线视为曲线。这是一个示例,但在我的实际项目中可以。
  • 能够在不是它的派生类的线上设置距离是一个强烈的迹象,表明您的类层次结构设计不当。有一些例外情况,因此设计是一个好主意,但这种情况很少见。
【解决方案2】:

由于您希望它在一个类中可设置但在其他类中不可设置,因此我通常不会为“特殊”的类(本例中的 setter)使用属性。

public class Segment
{
    protected int _distance;
    public int Distance { get { return _distance; } }
}

public class Line : Segment
{
    public int SetDistance(int distance) { _distance = distance; }
}

【讨论】:

  • 是的,添加公共方法...这就是我所做的。备注距离应该是段中的“抽象”成员。如果没有其他解决方案,我将继续使用这个。但是拥有一个属性 + 一个 Set 方法有点奇怪:)
【解决方案3】:
public class Segment
{
    private int distance;
    public virtual int Distance
    {
        get { return distance; }
        set { distance = value; }
    }
}

public class Line : Segment
{
    public override int Distance
    {
        get { return base.Distance; }
        set
        {
            // do nothing
        }
    }
}

编辑版本:

    public abstract class Segment
    {            
        public abstract int Distance { get; set; }
    }

    public class Line : Segment
    {
        private int distance;
        public override int Distance
        {
            get { return distance; }
            set
            {
                // do nothing
            }
        }
    }

【讨论】:

  • 好的,现在线路应该设置distance = value; PoliLine 不应该。这个想法是用户应该停止编译时间以将距离设置为 Poliline。如果不是,他可以说我的代码不起作用,并且有理由。这不是很合适的代码。在运行时绕过它的一种方法是抛出一个异常......
  • 感谢您的帮助,但是说设计不连贯而没有一些争论就像在说“你很愚蠢”。
  • 不,Serhio,我没有说你很愚蠢。我也没有暗示。我说你的设计语无伦次。
  • 经过进一步审查,我认为您的设计实际上是工程杰作。毫无疑问,它将成为未来教科书的一部分。
猜你喜欢
  • 2018-10-17
  • 2010-12-02
  • 1970-01-01
  • 2011-11-16
  • 1970-01-01
  • 1970-01-01
  • 2015-09-03
  • 2011-11-08
  • 2020-02-23
相关资源
最近更新 更多