简体   繁体   中英

How to decide between an Interface or Base Class for an new implementation?

When it comes to implementation, how should i decide to go for an base type or an Interface ? I tried to work out on few examples but i don't get the complete idea :(

Examples on how and why would be greatly appreciated..

A base class, abstract or not, can contain implemented members. An interface cannot. If all of your implementations are going to perform similarly, a base class might be the way to go because all of your child classes can share the same implementations of the members on the base class. If they aren't going to share implementations, then an interface might be the way to go.

Example:

class Person
{
    string Name { get; set; }
}

class Employee : Person
{
    string Company { get; set; }
}

It makes sense for Employee to inherit from Person because the Employee class doesn't have to define a Name property because it shares the implementation.

interface IPolygon
{
    double CalculateArea()
}

class Rectangle : IPolygon
{
    double Width { get; set; }
    double Height { get; set; }

    double CalculateArea()
    {
        return this.Width * this.Height;
    }
}

class Triangle : IPolygon
{
    double Base { get; set; }
    double Height { get; set; }

    double CalculateArea()
    {
        return 0.5 * this.Base * this.Height;
    }
}

Because Rectangle and Triangle have such differing implementations of CalculateArea , it doesn't make sense for them to inherit from a base class.

If you make a base class, and find that in only contains abstract members, you may as well just use an interface.

And, as j__m states, you cannot inherit from multiple base classes, but you can implement multiple interfaces.

I usually define interfaces first, and if I find myself duplicating code in my implementations, I create a base class that implements the interface, and make my implementations inherit from it.

To decide whether to use an abstract class or an interface, I find this article very helpful Source :

A good way to distinguish between a case for the one or the other for me has always been the following:

  1. Are there many classes that can be "grouped together" and described by one noun ? If so, have an abstract class by the name of this noun, and inherit the classes from it. (A key decider is that these classes share functionality, and you would never instantiate just an Animal ... you would always instantiate a certain kind of Animal : an implementation of your Animal base class) Example : Cat and Dog can both inherit from abstract class Animal , and this abstract base class will implement a method void Breathe() which all animals will thus do in exactly the same fashion. (I might make this method virtual so that I can override it for certain animals, like Fish, which does not breath the same as most animals).

  2. What kinds of verbs can be applied to my class, that might in general also be applied to others? Create an interface for each of these verbs. Example : All animals can be fed, so I will create an interface called IFeedable and have Animal implement that. Only Dog and Horse are nice enough though to implement ILikeable - I will not implement this on the base class, since this does not apply to Cat .

Please also look at this Interface vs Base class question.

One of the reasons to go with Abstract classes are when we have to enforce some initialization(like states via the constructor).

Interface doesn't allow you to define Constructor's contracts.

In the below example, every Animal object SHOULD have a NAME. This cannot be enforced via an Interface.

public abstract class Animal
{
    public Animal(string name)
    {
        this.Name = name;
    }

    public string Name 
    { 
        get; 
        private set; 
    }
}

public class Cat : Animal
{
    public Cat(string name)
        : base(name)
    {

    }

    string NoOfLegs { get; set; }
}



class Program
{
    static void Main(string[] args)
    {
        Animal aCat = new Cat("a");
    }
}

Actually they're not necessarily mutually exclusive. You can use both depending on how your code implementation evolves.

An interface is usually the enunciation of a contract. It defines an expected behaviour, that the implementors should honour. And it is usually considered a good practice to code your public api against interfaces . That way you reduce the coupling to your implementations' details and allow for easier refactoring and maintenance of your code. Now what qualifies as public api, is software components that embody the high-level interaction defined in your design and are intended to be reusable either by yourself and other within the same project or within several projects of independent scope.

A base class is already part of the implementation . Whether it implements an interface or not. And it it ties its potential hierarchy to specific implementations details: object state, overridable or non overridable methods, etc.

Interfaces are a more flexible construct. You can only have one base class, but you can implement many interfaces. If you need an object to support multiple behaviors, but more than one of those behaviors requires a specific base class, then you won't be able to do so.

As Dan notes base classes have a convenience advantage in many languages in that you can provide a base implementation. To do this with an interface requires you to create a class that provides the base implementation and then manually delegate your implementation of each interface method to that class - not nearly as convenient.

I find an analogy helps here:

Abstract Base Class:- A car manufacturer may develop a petrol engine which has some variants (1.6, 2L etc). The engine block casting could be considered the abstract base class , ie it defines the basic shape and features of the engine. A 2L version may have a larger cylinder head etc.

Interfaces:- The engine may also use various off-the-shelf components, eg alternator, radiator, starter motor etc and so it has to implement interfaces defined by these components. These components were typically designed without knowledge of the engines that may use them.

You can basically use both together if you need. But generally base class you can use for some methods or properties that you use in inherited classes too. If you make a base class it is better you make it abstract; than you will be more flexible by using virtual methods in base class an override it in inherited classes and use in diffrent way.

With interfaces you are more flexible. First of everything you make a declaration between classes that inherited from this interface. With this

  • you make your code more readable
  • you seperate your concepts, like a class inherited from interface A can connect Mssql database but another one can connect Mysql database.
  • yor code becomes more maintable; Interfaces helps to reduce coupling and therefore allow you to easily interchange implementations for the same concept without the underlying code being affected
  • You can use dependency injection
  • You can create unittest easier.

    You can have a look this question here for more information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM