是否可以使用相同的接口定义但提供不同的行为?

时间:2009-03-02 23:21:32

标签: c# oop

我的问题摘要是“我有2个共享一个公共接口的类,但是这两个类在属性方面有不同的行为。如果参数值无效,则一个接口抛出异常,另一个接口更新其内部状态处理无效值。这两个类可以共享相同的接口,还是应该定义两个接口以向开发人员表明这两个具有不同的行为?“

我会尝试用一些代码澄清一下。我的界面定义如下。

public interface IStationDictionary
{
    bool this[string stationId] { get; set; }
}

实现接口的类,此类用于设置数字IO板上的输出端口。

public class DigitalStationAdapter : IStationDictionary
{
    public bool this[string stationId]
    {
        get { return ports[stationId].Value; }
        set { ports[stationId].Value = value; }
    }

    public void AddDigitalStation(string stationId, DigitalIoPort port)
    {
        ports.Add(stationId, port);
    }

    private IDictionary<string, DigitalIoPort> ports = new Dictionary<string, DigitalIoPort>();
}

我还有一个类,记录哪些站点的值已更改,以便这些更改可以推广到数字IO。

public class StationTransitions : IStationDictionary
{
    public bool this[string stationId]
    {
        get
        {
            bool result = false;

            if(changes.ContainsKey(stationId))
                result = changes[stationId];

            return result;
        }
        set
        {
            if(!changes.ContainsKey(stationId))
                changes.Add(stationId, value);
            else
                changes[stationId] = value;
        }
    }

    public IDictionary GetChanges()
    {
        IDictionary<string, bool> result = changes;

        changes = new Dictionary<string, bool>

        return result;
    }

    private IDictionary<string, bool> changes = new Dictionary<string, bool>();
}

因此,当两个类都实现相同的接口时,如果您尝试使用不在字典中的stationId访问索引器,DigitalStationAdapter将抛出KeyNotFoundException。然而,StationTransitions将成功,即不同的行为。这没关系,我认为接口用于定义行为和结构?

基思。

1 个答案:

答案 0 :(得分:2)

这很好。可以这样想:确定任何继承关系是否“ok”的关键是Liskov substitution principle.这要求期望基类的代码应该能够在不知道它的情况下使用派生类。这意味着方法的前提条件不能在派生类中得到强化,但可以被削弱。接口只是基类的特例。

在您的情况下,接口的隐式前提条件是输入在您定义时有效。所有需要基类的代码都应该采用这种前提条件,避免传递无效数据或准备处理异常。在更新其内部状态以处理无效输入的具体类中,您正在弱化前提条件。就Liskov替代原则而言,这是可以接受的。

另一方面,如果您要使类自动处理无效输入而不抛出基类,并使类抛出后代,这将是不好的,因为代码期望基类无法使用派生类,就好像它是基类一样。它必须知道派生类来处理可能的异常。