Default Interface Methods. What is deep meaningful difference now, between abstract class and interface?

2.9k views Asked by At

I know that an abstract class is a special kind of class that cannot be instantiated. An abstract class is only to be sub-classed (inherited from). In other words, it only allows other classes to inherit from it but, it cannot be instantiated. The advantage is that it can enforce certain hierarchies for all the subclasses. In simple words, it is a kind of contract that forces all the subclasses to carry on the same hierarchies or standards.

Also I know that An interface is not a class. It is an entity that is defined by the word Interface. An interface has no implementation; it only has the signature or in other words, just the definition of the methods without the body. As one of the similarities to Abstract class, it is a contract that is used to define hierarchies for all subclasses or it defines specific set of methods and their arguments. The main difference between them is that a class can implement more than one interface but can only inherit from one abstract class. Since C# doesn’t support multiple inheritance, interfaces are used to implement multiple inheritance.

When we create an interface, we are basically creating a set of methods without any implementation that must be overridden by the implemented classes. The advantage is that it provides a way for a class to be a part of two classes: one from inheritance hierarchy and one from the interface.

When we create an abstract class, we are creating a base class that might have one or more completed methods but at least one or more methods are left uncompleted and declared abstract. If all the methods of an abstract class are uncompleted then it is same as an interface.

BUT BUT BUT

I noticed that we will have Default Interface Methods in C# 8.0

Maybe I'm asking it because I have only 1-2 years of experience in programming, but what would be main difference between abstract class and interface now?

I know that we can't make state in interface, will it be only one difference between them?

6

There are 6 answers

1
Ousmane D. On BEST ANSWER

There is not a lot of difference between the two apart from the obvious fact that abstract classes can have state and interfaces cannot. Default methods or also known as virtual extension methods have actually been available in Java for a while. The main drive for default methods is interface evolution which means being able to add methods to an interface in future versions without breaking source or binary compatibility with existing implementations of that interface.

another couple of good points mentioned by this post:

0
vasil oreshenski On

Another thing which still makes the interface unique is covariance / contravariance.

To be honest, never found myself in situation where a default impl. in interface was the solution. I am a bit sceptical about it.

1
tmaj On

Both abstract classes and the new default interface methods have their appropriate uses.

A. Reasons

Default interface methods have not been introduced to substitute abstract classes.

What's new in C# 8.0 states:

This language feature enables API authors to add methods to an interface in later versions without breaking source or binary compatibility with existing implementations of that interface. Existing implementations inherit the default implementation.

This feature also enables C# to interoperate with APIs that target Android or Swift, which support similar features. Default interface methods also enable scenarios similar to a "traits" language feature.

B. Functional differences

There are still significant differences between an abstract class and an interface (even with default methods).

Here are a few things that an interface still cannot have/do while an abstract class can:

  • have a constructor,
  • keep state,
  • inherit from non abstract class,
  • have private methods.

C. Design

While default interface methods make interfaces even more powerful, abstract/base classes and interfaces still represent fundamentally different relationships.

(From When should I choose inheritance over an interface when designing C# class libraries?)

  • Inheritance describes an is-a relationship.
  • Implementing an interface describes a can-do relationship.
0
Julian On

Conceptual

First of all, there is a conceptual difference between a class and an interface.

  • A class should describe an "is a" relationship. E.g. a Ferrari is a Car
  • An interface should describe a contract of a type. E.g. A Car has a steering wheel.

Currently abstract classes are sometimes used for code reuse, even when there is no "is a" relationship. This pollutes the OO design. E.g. FerrariClass inherits from CarWithSteeringWheel

Benefits

  • So from above, you could reuse code without introducing a (conceptually wrong) abstract class.
  • You could inherit from multiple interfaces, while an abstract class is only single inheritance
  • There is co- and contravariance on interfaces and not on classes in C#
  • It's easier to implement an interface because some methods have default implementations. This could save a lot of work for an implementer of the interface, but the user won't see the difference :)
  • But most important for me (as I'm a library maintainer), you could add new methods to an interface without making a breaking change! Before C# 8, if an interface was publicly published, it should be fixed. Because changing the interface could break a lot.

The logger interface

This example shows some of the benefits.

You could describe a (oversimplified) logger interface as follows:

interface ILogger
{
    void LogWarning(string message);

    void LogError(string message);

    void Log(LogLevel level, string message);
}

Then a user of that interface could log easily as warning and error using LogWarning and LogError. But the downside is that an implementer must implement all the methods.

An better interface with defaults would be:

interface ILogger
{
    void LogWarning(string message) => Log(LogLevel.Warning, message);

    void LogError(string message) => Log(LogLevel.Error, message);

    void Log(LogLevel level, string message);
}

Now a user could still use all the methods, but the implementer only needs to implement Log. Also, he could implement LogWarning and LogError.

Also, in the future you might like to add the logLevel "Catastrophic". Before C#8 you could not add the method LogCatastrophic to ILogger without breaking all current implementations.

0
Julien Couvreur On

Two main differences:

  • Abstract classes can have state, but interfaces cannot.
  • A type can derive from a single abstract class, but can implement multiple interfaces.

There are some other, smaller, differences when it comes to default modifiers.

0
Robin B On

The only main difference coming to my mind is that you can still overload the default constructor for abstract classes which interfaces will never have.

abstract class LivingEntity
{
    public int Health
    {
        get;
        protected set;
    }


    protected LivingEntity(int health)
    {
        this.Health = health;
    }
}

class Person : LivingEntity
{
    public Person() : base(100)
    { }
}

class Dog : LivingEntity
{
    public Dog() : base(50)
    { }
}