Do/Can Abstract Classes Replace Interfaces

Do/can abstract classes replace interfaces?

Not always:

  • a class can extend only one class
  • a class can implement more than one interface

Sun docs make a more detailed comparison:

Abstract Classes versus Interfaces

Unlike interfaces, abstract classes can contain fields that are not static and final, and they can contain implemented methods. Such abstract classes are similar to interfaces, except that they provide a partial implementation, leaving it to subclasses to complete the implementation. If an abstract class contains only abstract method declarations, it should be declared as an interface instead.

Multiple interfaces can be implemented by classes anywhere in the class hierarchy, whether or not they are related to one another in any way. Think of Comparable or Cloneable, for example.

By comparison, abstract classes are most commonly subclassed to share pieces of implementation. A single abstract class is subclassed by similar classes that have a lot in common (the implemented parts of the abstract class), but also have some differences (the abstract methods).

Can we replace abstract class with Interface with Default Methods in C#

No, abstract classes still have their place. In particular, abstract classes can declare fields (often via automatically implemented properties these days), which interfaces still can't. They can also define constructors, and perform validation in them.

Here's an example of something you couldn't do with an interface:

public abstract class NamedObject
{
public string Name { get; }

protected NamedObject(string name) =>
Name = name ?? throw new ArgumentNullException(nameof(name));

// Abstract methods here
}

Obviously it wouldn't really be called NamedObject - there'd be a business-specific reason for it to be abstract, which would determine the name. But the behaviour here is behaviour that can't be put in an interface.

When to use an interface instead of an abstract class and vice versa?

I wrote an article about that:

Abstract classes and interfaces

Summarizing:

When we talk about abstract classes we are defining characteristics of an object type; specifying what an object is.

When we talk about an interface and define capabilities that we promise to provide, we are talking about establishing a contract about what the object can do.

What is the difference between an interface and abstract class?

Interfaces

An interface is a contract: The person writing the interface says, "hey, I accept things looking that way", and the person using the interface says "OK, the class I write looks that way".

An interface is an empty shell. There are only the signatures of the methods, which implies that the methods do not have a body. The interface can't do anything. It's just a pattern.

For example (pseudo code):

// I say all motor vehicles should look like this:
interface MotorVehicle
{
void run();

int getFuel();
}

// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{

int fuel;

void run()
{
print("Wrroooooooom");
}

int getFuel()
{
return this.fuel;
}
}

Implementing an interface consumes very little CPU, because it's not a class, just a bunch of names, and therefore there isn't any expensive look-up to do. It's great when it matters, such as in embedded devices.


Abstract classes

Abstract classes, unlike interfaces, are classes. They are more expensive to use, because there is a look-up to do when you inherit from them.

Abstract classes look a lot like interfaces, but they have something more: You can define a behavior for them. It's more about a person saying, "these classes should look like that, and they have that in common, so fill in the blanks!".

For example:

// I say all motor vehicles should look like this:
abstract class MotorVehicle
{

int fuel;

// They ALL have fuel, so lets implement this for everybody.
int getFuel()
{
return this.fuel;
}

// That can be very different, force them to provide their
// own implementation.
abstract void run();
}

// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
void run()
{
print("Wrroooooooom");
}
}

Implementation

While abstract classes and interfaces are supposed to be different concepts, the implementations make that statement sometimes untrue. Sometimes, they are not even what you think they are.

In Java, this rule is strongly enforced, while in PHP, interfaces are abstract classes with no method declared.

In Python, abstract classes are more a programming trick you can get from the ABC module and is actually using metaclasses, and therefore classes. And interfaces are more related to duck typing in this language and it's a mix between conventions and special methods that call descriptors (the __method__ methods).

As usual with programming, there is theory, practice, and practice in another language :-)

Replace switch case: interface vs abstract class

I want to know which one is better in such case? I've noticed that people tend to go with interfaces but can someone explain why?

The inheritance dependency is the strongest of all dependencies, because your sub classes inherit all the dependencies that your parent classes have. E.g. if a parent class depends upon some library your sub class can only be used if that library is on the classpath. Maybe you faced a indirectly referenced from class file error sometime ago in your IDE. This error occures because of dependencies of your parent classes that are not on the compile classpath.

That's why most of the developers tend to use interfaces and keep the interface signature as easy as possible. I mean that you should not use any library classes in an interface's signature. Only use POJOs so that your interfaces only depend on pure Java and not depend upon other libraries.

Abstract classes can be very useful when you want to implement the template method pattern. The template method defines an abstract algorithm that can be extended by sub classes. They just override or implement abstract methods from the parent class. Abstract classes can implement behavior. So if there is a common behavior to all of your sub classes an abstract class might be good choice. But keep in mind that abstractions should be stable. If you have abstractions that change often all of your sub classes are affected. This problem can drammatically increase with each hierarchy level and make your code hard to maintain. A good rule is that the higher a class is in your hierarchy the more stable it must be.

When do I have to use interfaces instead of abstract classes?

From Java How to Program about abstract classes:

Because they’re used only as superclasses in inheritance hierarchies,
we refer to them as abstract superclasses. These classes cannot be
used to instantiate objects, because abstract classes are incomplete.

Subclasses must declare the “missing pieces” to become “concrete” classes,
from which you can instantiate objects. Otherwise, these subclasses, too,
will be abstract.

To answer your question "What is the reason to use interfaces?":

An abstract class’s purpose is to provide an appropriate superclass
from which other classes can inherit and thus share a common design.

As opposed to an interface:

An interface describes a set of methods that can be called on an
object, but does not provide concrete implementations for all the
methods
... Once a class implements an interface, all objects of that class have
an is-a relationship with the interface type, and all objects of the
class are guaranteed to provide the functionality described by the
interface.
This is true of all subclasses of that class as well.

So, to answer your question "I was wondering when I should use interfaces", I think you should use interfaces when you want a full implementation and use abstract classes when you want partial pieces for your design (for reusability)

Can we replace Abstract Classes with Interface having Extension Methods?

Extension methods were introduced in C# because a very particular requirement.

When they were designing LINQ they realized that they wouldn't want to create a new interface which would contain all known LINQ methods like Where or Select, because it would mean that any enumerable or collection implementation would need to implement it.

Above mentioned fact has an important drawback: it would need to extensively change the source code of a lot of classes from the Base Class Library and any third-party library or project implementing custom collections couldn't take advantage of LINQ at all.

Then they thought about an approach that could directly work with iterators (i.e. IEnumerator<T>) and that could be compatible with any IEnumerable<T> without having to modify any existing code but just adding new code to new assembly members.

And they invented extension methods, which would be implemented like static methods and they would act as instance members of a given type.

Since the inception of extension methods, they've been implemented in many other scenarios, but they always cover these two use cases:

  1. I've a large code base and I want to offer a functionality to all types deriving (classes) or implementing (interfaces) some other type without having to modify them implementing a new interface across a lot of code (increasing the chance of introducing new bugs).

  2. I don't own the source code of some project and I want to extend some types to support some new methods.

Anything outside these use cases is an abuse of extension methods.

Extension methods aren't a replacement to regular class-based object-oriented programming.

Interface vs Abstract Class (general OO)

While your question indicates it's for "general OO", it really seems to be focusing on .NET use of these terms.

In .NET (similar for Java):

  • interfaces can have no state or implementation
  • a class that implements an interface must provide an implementation of all the methods of that interface
  • abstract classes may contain state (data members) and/or implementation (methods)
  • abstract classes can be inherited without implementing the abstract methods (though such a derived class is abstract itself)
  • interfaces may be multiple-inherited, abstract classes may not (this is probably the key concrete reason for interfaces to exist separately from abtract classes - they permit an implementation of multiple inheritance that removes many of the problems of general MI).

As general OO terms, the differences are not necessarily well-defined. For example, there are C++ programmers who may hold similar rigid definitions (interfaces are a strict subset of abstract classes that cannot contain implementation), while some may say that an abstract class with some default implementations is still an interface or that a non-abstract class can still define an interface.

Indeed, there is a C++ idiom called the Non-Virtual Interface (NVI) where the public methods are non-virtual methods that 'thunk' to private virtual methods:

  • http://www.gotw.ca/publications/mill18.htm
  • http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface

How should I have explained the difference between an Interface and an Abstract class?

I will give you an example first:

public interface LoginAuth{
public String encryptPassword(String pass);
public void checkDBforUser();
}

Suppose you have 3 databases in your application. Then each and every implementation for that database needs to define the above 2 methods:

public class DBMySQL implements LoginAuth{
// Needs to implement both methods
}
public class DBOracle implements LoginAuth{
// Needs to implement both methods
}
public class DBAbc implements LoginAuth{
// Needs to implement both methods
}

But what if encryptPassword() is not database dependent, and it's the same for each class? Then the above would not be a good approach.

Instead, consider this approach:

public abstract class LoginAuth{
public String encryptPassword(String pass){
// Implement the same default behavior here
// that is shared by all subclasses.
}

// Each subclass needs to provide their own implementation of this only:
public abstract void checkDBforUser();
}

Now in each child class, we only need to implement one method - the method that is database dependent.



Related Topics



Leave a reply



Submit