当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - Recommendations for Abstract Classes vs Interfaces

问题描述:

I know the difference between interface and abstract class. Now I would like to know where exactly i need to use interface over abstract class, vice versa.

The article i referred Recommendations for Abstract Classes vs. Interfaces

In that

Here are some recommendations to help you to decide whether to use an interface or an abstract class to provide polymorphism for your components.

  1. If you anticipate creating multiple versions of your component, create

    an abstract class. Abstract classes provide a simple and easy way to

    version your components. By updating the base class, all inheriting

    classes are automatically updated with the change. Interfaces, on the

    other hand, cannot be changed once created. If a new version of an

    interface is required, you must create a whole new interface.

  2. If the functionality you are creating will be useful across a wide range of disparate objects, use an interface. Abstract classes should

    be used primarily for objects that are closely related, whereas

    interfaces are best suited for providing common functionality to

    unrelated classes.

  3. If you are designing small, concise bits of functionality, use

    interfaces. If you are designing large functional units, use an

    abstract class.

  4. If you want to provide common, implemented functionality among all implementations of your component, use an abstract class. Abstract classes allow you to partially implement your class, whereas interfaces contain no implementation for any members.

I am not sure about the point #3. Do i need to place all the small functions of my component into interface?

Any real world/understandable example which will help me to choose each?

网友答案:

Immagine that you are creating an animation and you have vehicle and person both should inherits from IMovable hence here independently from the class origin you should be able to initialize an array of IMovable and call Move Method defined in your interface this will let you able when you call move to let the person walk and the wheel of the car turn with a single call to method, because here every class has his own Behavior of implementing Move for the second part take a look at this link http://dofactory.com/Patterns/PatternAbstract.aspx#_self2 as it explain perfectly why you should use abstract instead of interface for example carnivore have a common method Eat which can be used from all the children class by default as carnivore should eat herbivore.
Hope this help

网友答案:

I usually just look at the code and try to figure out whether there are actually common methods that may be used 'as is' for different objects within the hierarchy in question. I.e. if classes A and B inherit the same common ancestor C, because they are similar - is there any functionality that will be identical for both of them? in that case, C may be an abstract class with method doSomething() that needs to be specified only in C ( If C was an interface, both A and B would have to offer their own implementations of the doSomething() method).

I think that is what is hinted by #3, if you design large functional units using interfaces, everything needs to be reimplemented which implies a lot of code. And if there are no "common" methods doing similar things, the implementations are too different and should simply not belong to the same interface. (However, this reasoning largely assumes that all the important classes used are part of some appropriate inheritance structure, which may not always be the case, e.g. if you work with 3rd party API.)

网友答案:

Interfaces are like contracts. If any part of your code should depend on the presence of some methods or properties, an interface is a good idea. It also provides more space for unit testing.

Many times I define both an interface and abstract class implementing it. This way, you can have an implementation of the interface without deriving from the base class.

As for real word example, consider a message gateway, for example. Please, note that the following implementation is not that OOP-perfect. I just didn't want to create so many classes and interfaces.

interface IMessageSender
{
    string From { get; set; }
    string To { get; set; }
    string Message { get; set; }

    void Send();
}

abstract class MessageSenderWithSubjectBase : IMessageSender
{
    string From { get; set; }
    string To { get; set; }
    string Message { get; set; }

    string Subject { get; set; }

    abstract void Send();
}

class EmailSender : MessageSenderWithSubjectBase
{
    override void Send() { // send email }
}

class SmsSender : IMessageSender
{
    override void Send() { // send sms }
}

See, an SMSes does not have a subject. You could derive from the abstract class as well and just ignore the subject, but that is not a clear design. Not to mention situation when there are common method in a base class you know that you don't need at all. Instead you can create a base class for messages without subject or just implement the the interface.

Somewhere in code when you will need to send a message, you will probably get a message sender from some sort of a factory and you can rely that it will be able to send your message because it implements the interface. You can be abstract like that.

Although this answer does not directly answer your question, it is because I don't think that you can create rules like those you have read. Given a time and many lines of code and you will eventually understand when you need interface, abstract class or both simultaneously.

网友答案:

To answer point (3).

If you are designing small, concise bits of functionality, use interfaces. If you are designing large functional units, use an abstract class.

Example would be small functionalities such as helper functions or reusable code block. I recently implemented a validation provider, which has a single method Validate and used across logically related and unrelated concrete objects.

网友答案:

Most of the time, when the discussion comes up between deciding if you should use interfaces or abstract classes, it ends up with definitions of how to use them, but not always why and when? Also the obvious other concrete classes and utility classes that you may end up using as well aren't always brought up. Really, in my thinking the correct way to answer the question is to determine the context you are dealing with regarding the domain or entity objects, namely what is your use case?

From a very high level, Java consists of objects (entities or domain objects that can model objects in the real world) that communicate with each other using methods. In any event, you want to model behavior with interfaces and use abstract classes when you have inheritance.

I do this using a top down and then bottom up approach. I start looking for inheritance by looking at the use case and seeing what classes I will need. Then I look to see if there is a superClassOrInterfaceType (since both classes and interfaces define types, I'm combining them into a one word for simplicity. Hopefully it doesn't make it more confusing) domain object that would encompass all the objects, as in a superClassOrInterfaceType of vehicle if I'm working on a use case dealing with subtypeClassOrInterfaceTypes like: cars, trucks, jeeps, and motorcycles for example. If there is a hierarchy relationship, then I define the superClassOrInterfaceType and subtypeClassOrInterfaceTypes.

As I said, what I generally do first is to look for a common domain superClassOrInterfaceType for the objects I'm dealing with. If so, I look for common method operations between the subtypeClassOrInterfaceTypes. If not, I look to see if there are common method implementations, because even though you may have a superClassOrInterfaceType and may have common methods, the implementations may not favor code reuse. At this point, if I have common methods, but no common implementations, I lean towards an interface. However, with this simplistic example, I should have some common methods with some common implementations between the vehicle subtypeClassOrInterfaceTypes that I can reuse code with.

On the other hand, if there is no inheritance structure, then I start from the bottom up to see if there are common methods. If there are no common methods and no common implementations, then I opt for a concrete class.

Generally, if there is inheritance with common methods and common implementations and a need for multiple subtype implementation methods in the same subtype, then I go with an abstract class, which is rare, but I do use it. If you just go with Abstract classes just because there is inheritance, you can run into problems if the code changes a lot. This is detailed very well in the example here: Interfaces vs Abstract Classes in Java, for the different types of domain objects of motors. One of them required a dual powered motor, that required multiple subtype implementation methods to be used in a single subtype class.

To sum it all up, as a rule you want to define behaviors (what the objects will do) with interfaces and not in Abstract classes. Abstract classes focus on an implementation hierarchy and code reuse.

Here are some links that go into greater details on this.

Thanks Type & Gentle Class

The Magic behind Subtype Polymorphism

Maximize Flexibility with Interfaces & Abstract Classes

Interfaces vs Abstract Classes in Java

分享给朋友:
您可能感兴趣的文章:
随机阅读: