在以下情况下,接口或抽象类是否更好?

时间:2011-03-31 01:47:28

标签: oop

假设我有一些程序可以提取航空公司数据。每个航空公司的数据使用一个不同的系统,我需要从中提取数据(xml)。由于每个系统的不同,基本上xml是不同的,也许是一些推动,我决定为每个航空公司系统实施一个接口。我发现虽然每家航空公司虽然在很多方面都有所不同,但也包含很多相似之处,所以如果我首先使用界面方式,我可能需要这样做:

public interface IAirlineSystem {
    public void PullData();
}

现在,对于每个航空公司系统(我正在建立这些名称),我可能会这样做:

public class Oberon : IAirlineSystem {
    string Name {get;set;}
    int Code {get;set;}
    public void Initialize()
    {
        //initialize code here
    }
    public void PullData()
    {
       //code here
    }
}

以上只是一个航空公司系统,但想象我有更多(如+10),另一个可能是:

public class AirSys: IAirlineSystem {
    string Name {get;set;}
    int Code {get;set;}
    public void Initialize()
    {
        //initialize code here
    }
    public void PullData()
    {
       //code here
    }
}

在上面的代码中:

每个航空公司系统都有名称和代码属性。 Initialize包含每个实现的完全相同的代码,PullData对每个系统都是唯一的。由于类中的重复,我可以使用抽象类来保存Initialize方法的代码。我听说实际混合接口和抽象类是一种好习惯,使用我的航空公司系统示例会是什么样的例子呢?

另一件事是假设我在接口中有另一种方法叫做ValidateData,但并非所有航空公司系统都需要调用它,但是如果我把它放在一个接口中,我需要实现一个空方法如果不需要的话。有没有办法可以防止不必这样做。这是使用抽象类的另一个原因,可能是使用虚方法,因此可以根据需要覆盖它。如果我将ValidateData作为抽象方法,它仍然需要实现,对吧?

2 个答案:

答案 0 :(得分:1)

您的解释似乎指向使用抽象类。你可以有一个抽象类,它有一个Initialize方法的实现,你不需要在Oberon和AirSys子类中重复它。 PullData可以是一个抽象方法,然后在单独的子类中实现。是的,只有需要ValidateData方法的类才能实现它。

示例是:

public abstract class AirlineSystemBase
{
    string Name { get; set; }
    int Code { get; set; }

    public void Initialize()
    {
        //code goes here
    }

    public abstract void PullData();

}

public class Oberon : AirlineSystemBase
{
    public override void PullData()
    {
        //code goes here
    }
}

public class AirSys : AirlineSystemBase
{
    /// <summary>
    ///     that is if say only AirSys class had a need for this ValidateData() method
    /// </summary>
    public void ValidateData()
    {
        //code goes here
    }

    public override void PullData()
    {
        //code goes here
    }

}

如果要同时使用接口和抽象类,请执行以下操作:

public interface IAirlineSystem
{
    void PullData();
    void ValidateData();
}

public abstract class AirlineSystemBase : IAirlineSystem
{
    string Name { get; set; }
    int Code { get; set; }

    public void Initialize()
    {
        //code goes here
    }

    public abstract void PullData();

    public virtual void ValidateData() 
    { 
        //code goes here
    }

}

public class Oberon : AirlineSystemBase
{
    public override void PullData()
    {
        //code goes here
    }
}

public class AirSys : AirlineSystemBase
{
    /// <summary>
    ///     that is if say only AirSys class had a need for this ValidateData() method
    /// </summary>
    public override void ValidateData()
    {
        //code goes here
    }

    public override void PullData()
    {
        //code goes here
    }

}

答案 1 :(得分:0)

一个例子,我会实现类似的东西:

public interface IAirlineSystem {
    public void PullData();
    public void ValidateData();
}

public abstract class BaseAirlineSystem : IAirlineSystem {
    string Name {get;set;}
    int Code {get;set;}

    public void Initialize()
    {
        // common initialize code here
    }        

    public virtual void ValidateData()
    {
       //empty, override when necessary
    }
}

示例实现:

public class AirSys: BaseAirlineSystem{
    public void PullData()
    {
        //code here
    }
 }