When designing my software, I began with interfaces since this seems to be the "standard". Then I switched to abstract classes because they seem better suited to the pro开发者_如何学运维blem at hand. However I'm not sure if I've missed out on some considerations when making this design choice. Other than domain specific issues which I have thought about what are the more general factors to consider when choosing between interfaces and abstracts classes?
I find the best option most of the time is to do both. That is not always possible when you are relying on something happening in the base class . Providing both an abstract base class and an interface allows the greatest latitude by implementers of your abstraction, again, as long as you don't require something happens by an implementer of the interface. If you require that something happens, then you don't want to provide an interface at all--and you would also need to make sure that your base class ensures this required action to ALWAYS occur...
Negative to doing both: more goo.
example pseudocode:
interface IVehicle
{
void PutCarInGear(Int speed);
}
abstract class Vehicle : IVehicle
{
public void PutCarInGear(Int speed)
{
//base implementation
}
}
Note that in this example, someone could make their own class that implements IVehicle
and then pass it to anything that takes an IVehicle
. That object would NOT need to be a child of the Vehicle
abstract class. If, therefore, you were to expect something specific to happen in the PutCarInGear()
method, it's quite likely that that new class would NOT fulfill that expectation. However, as long as it never matters what implementations of IVehicle
do, then it's the most flexible abstraction to have both an abstract base class AND an interface.
Inheritance defines similarity of composition. Interfaces define similarity of behavior. From there you have to decide if the composition is important enough to override the behavior.
If your interface also has reasonable default behavior for at least some of the functionality, you may want to use an abstract class to avoid common boilerplate code in all of the concrete implementations. Otherwise, use an interface.
Use an abstract class when you have multiple instances that reify the Template Method pattern.
Say you have three parsers. One deliminates the file's data by ",", another by " ", and another by "|"
You can then have a CommaParser, a SpaceParser and a PipeParser, all subclassing the Abstract Parser, and overriding the abstract method, getDelimiter()
Use an interface when the classes don't share implementation, but merely respond to the same method calls.
Keep it as a Abstract Class if its a “Is a” relationship and should do subset/all of the functionality. Keep it as interface if its a “Should Do” relationship.
精彩评论