oop - constructeur - différence entre classe et interface java




Quelle est la différence entre une interface et une classe abstraite? (20)

Quelle est exactement la différence entre une interface et une classe abstraite?


Interfaces

Une interface est un contrat : Le gars qui écrit l'interface dit, " hé, j'accepte les choses qui ont l'air de cette façon ", et le gars qui utilise l'interface dit " OK, la classe que j'écris ressemble à ça ".

Une interface est un shell vide . Il n'y a que les signatures des méthodes, ce qui implique que les méthodes n'ont pas de corps. L'interface ne peut rien faire. C'est juste un motif.

Par exemple (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;
    }
}

L'implémentation d'une interface consomme très peu de CPU, car ce n'est pas une classe, juste un tas de noms, et donc il n'y a pas de recherche coûteuse à faire. C'est génial quand c'est important, comme dans les appareils embarqués.

Cours abstraits

Les classes abstraites, contrairement aux interfaces, sont des classes. Ils sont plus chers à utiliser, car il y a une recherche à faire quand vous héritez d'eux.

Les classes abstraites ressemblent beaucoup aux interfaces, mais elles ont quelque chose de plus: Vous pouvez définir un comportement pour elles. Il s'agit plus d'un gars qui dit: «Ces cours devraient ressembler à ça, et ils ont cela en commun, alors remplissez les blancs!

Par exemple:

// 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");
    }
}

la mise en oeuvre

Alors que les classes abstraites et les interfaces sont supposées être des concepts différents, les implémentations rendent parfois cette affirmation fausse. Parfois, ils ne sont même pas ce que vous pensez qu'ils sont.

En Java, cette règle est fortement appliquée, tandis qu'en PHP, les interfaces sont des classes abstraites sans méthode déclarée.

En Python, les classes abstraites sont plus une astuce de programmation que vous pouvez obtenir du module ABC et qui utilise réellement des métaclasses, et donc des classes. Et les interfaces sont plus liées au typage du canard dans ce langage et c'est un mélange entre les conventions et les méthodes spéciales qui appellent des descripteurs (les méthodes __method__).

Comme d'habitude avec la programmation, il y a la théorie, la pratique et la pratique dans une autre langue :-)


C'est assez simple en fait.

Vous pouvez considérer une interface comme une classe qui ne peut avoir que des méthodes abstraites et rien d'autre.

Ainsi, une interface peut seulement "déclarer" et ne pas définir le comportement que vous voulez que la classe ait.

Une classe abstraite vous permet à la fois de déclarer (en utilisant des méthodes abstraites) et de définir (en utilisant des implémentations de méthodes complètes) le comportement que vous voulez que la classe ait.

Et une classe régulière ne vous permet que de définir, et non de déclarer, le comportement / les actions que vous voulez que la classe ait.

Une dernière chose,

En Java, vous pouvez implémenter plusieurs interfaces, mais vous ne pouvez en étendre qu'une (classe ou classe abstraite) ...

Cela signifie que l'héritage du comportement défini est limité à un seul par classe ... Par exemple, si vous voulez une classe qui encapsule le comportement des classes A, B et C, vous devez effectuer les opérations suivantes: Classe A étend B, Classe C étend A C'est un peu un tour d'avoir un héritage multiple ...

Interfaces d'autre part, vous pouvez simplement faire: l'interface C implémente A, B

Donc, en effet, Java ne prend en charge l'héritage multiple que dans le "comportement déclaré", c'est-à-dire les interfaces, et seulement l'héritage unique avec un comportement défini .. à moins que vous ne fassiez le tour comme je l'ai décrit ...

J'espère que cela a du sens.


Interface: Tourner (tourner à gauche, tourner à droite.)

Classe abstraite: Roue.

Classe: Volant, dérivé de la roue, expose Interface Turn

L'un est pour catégoriser le comportement qui peut être offert à travers un large éventail de choses, l'autre est pour modéliser une ontologie des choses.


Je construis un bâtiment de 300 étages

L' interface du bâtiment

  • Par exemple, Servlet (I)

Bâtiment construit jusqu'à 200 étages - partiellement achevé --- résumé

  • Implémentation partielle, par exemple, servlet générique et HTTP

Construction de bâtiments achevée - béton

  • Implémentation complète, par exemple, propre servlet

Interface

  • Nous ne savons rien de la mise en œuvre, seulement des exigences. Nous pouvons aller pour une interface.
  • Chaque méthode est publique et abstraite par défaut
  • C'est une classe abstraite 100% pure
  • Si nous déclarons public, nous ne pouvons pas déclarer privé et protégé
  • Si nous déclarons abstrait, nous ne pouvons pas déclarer final, statique, synchronisé, strictfp et natif
  • Chaque interface est publique, statique et finale
  • La sérialisation et le transitoire ne sont pas applicables, car nous ne pouvons pas créer d'instance pour l'interface.
  • Non volatile car c'est final
  • Chaque variable est statique
  • Lorsque nous déclarons une variable dans une interface, nous devons initialiser les variables lors de la déclaration
  • Instance et bloc statique non autorisés

Abstrait

  • Mise en œuvre partielle
  • Il a une méthode abstraite. Un ajout, il utilise du béton
  • Aucune restriction pour les modificateurs de méthode de classe abstraite
  • Aucune restriction pour les modificateurs de variable de classe abstraite
  • Nous ne pouvons pas déclarer d'autres modificateurs excepté abstrait
  • Aucune restriction pour initialiser les variables

Tiré du site Web de DurgaJobs


L'héritage est utilisé à deux fins:

  • Pour autoriser un objet à considérer les membres de données de type parent et les implémentations de méthode comme siennes.

  • Permettre qu'une référence à un objet d'un type soit utilisée par un code qui attend une référence à un objet supertype.

Dans les langages / frameworks qui supportent l'héritage multiple généralisé, il n'est souvent pas nécessaire de classer un type comme étant soit une "interface" soit une "classe abstraite". Cependant, les langages et frameworks populaires permettront à un type de considérer comme propres les membres de données ou les implémentations de méthodes d'un autre type, même s'ils permettent qu'un type soit substituable à un nombre arbitraire d'autres types.

Les classes abstraites peuvent avoir des membres de données et des implémentations de méthodes, mais ne peuvent être héritées que par des classes qui n'héritent d'aucune autre classe. Les interfaces ne mettent presque aucune restriction sur les types qui les implémentent, mais ne peuvent inclure aucun membre de données ou implémentation de méthode.

Il y a des moments où il est utile que les types soient substituables à beaucoup de choses différentes; Il y a d'autres moments où il est utile que les objets considèrent les membres de données de type parent et les implémentations de méthode comme les leurs. Faire une distinction entre les interfaces et les classes abstraites permet d'utiliser chacune de ces capacités dans les cas où cela est le plus pertinent.


La comparaison entre l'interface et la classe abstraite est fausse. Il devrait y avoir deux autres comparaisons à la place: 1) l' interface par rapport à la classe et 2) l' abstrait par rapport à la classe finale .

Interface par rapport à la classe

L'interface est un contrat entre deux objets. Par exemple, je suis un facteur et vous êtes un paquet à livrer. Je m'attends à ce que vous connaissiez votre adresse de livraison. Quand quelqu'un me donne un paquet, il doit connaître son adresse de livraison:

interface Package {
  String address();
}

La classe est un groupe d'objets qui obéissent au contrat. Par exemple, je suis une boîte du groupe "Box" et j'obéis au contrat requis par le facteur. En même temps j'obéis à d'autres contrats:

class Box implements Package, Property {
  @Override
  String address() {
    return "5th Street, New York, NY";
  }
  @Override
  Human owner() {
    // this method is part of another contract
  }
}

Résumé vs Final

La classe abstraite est un groupe d'objets incomplets. Ils ne peuvent pas être utilisés, car ils manquent certaines parties. Par exemple, je suis une boîte GPS-consciente abstraite - je sais comment vérifier ma position sur la carte:

abstract class GpsBox implements Package {
  @Override
  public abstract String address();
  protected Coordinates whereAmI() {
    // connect to GPS and return my current position
  }
}

Cette classe, si elle a été héritée / étendue par une autre classe, peut être très utile. Mais par lui-même - c'est inutile, puisqu'il ne peut pas avoir d'objets. Les classes abstraites peuvent être des éléments de construction des classes finales.

La classe finale est un groupe d'objets complets, qui peuvent être utilisés, mais ne peuvent pas être modifiés. Ils savent exactement comment travailler et quoi faire. Par exemple, je suis une boîte qui va toujours à l'adresse indiquée lors de sa construction:

final class DirectBox implements Package {
  private final String to;
  public DirectBox(String addr) {
    this.to = addr;
  }
  @Override
  public String address() {
    return this.to;
  }
}

Dans la plupart des langages, comme Java ou C ++, il est possible d'avoir juste une classe , ni abstraite ni finale. Une telle classe peut être héritée et peut être instanciée. Je ne pense pas que cela soit strictement en accord avec le paradigme orienté objet.

Encore une fois, la comparaison d'interfaces avec des classes abstraites n'est pas correcte.


Le moyen le plus court de le résumer est qu'une interface est:

  1. Entièrement abstrait, en dehors static méthodes default et static ; while it has definitions (method signatures + implementations) for default and static methods, it only has declarations (method signatures) for other methods.
  2. Subject to laxer rules than classes (a class can implement multiple interface s, and an interface can inherit from multiple interface s). All variables are implicitly constant, whether specified as public static final or not. All members are implicitly public , whether specified as such or not.
  3. Generally used as a guarantee that the implementing class will have the specified features and/or be compatible with any other class which implements the same interface.

Meanwhile, an abstract class is:

  1. Anywhere from fully abstract to fully implemented, with a tendency to have one or more abstract methods. Can contain both declarations and definitions, with declarations marked as abstract .
  2. A full-fledged class, and subject to the rules that govern other classes (can only inherit from one class), on the condition that it cannot be instantiated (because there's no guarantee that it's fully implemented). Can have non-constant member variables. Can implement member access control, restricting members as protected , private , or private package (unspecified).
  3. Generally used either to provide as much of the implementation as can be shared by multiple subclasses, or to provide as much of the implementation as the programmer is able to supply.

Or, if we want to boil it all down to a single sentence: An interface is what the implementing class has , but an abstract class is what the subclass is .


Le point principal est que:

  • L'abstrait est orienté objet . Il offre les données de base qu'un «objet» devrait avoir et / ou des fonctions qu'il devrait être capable de faire. Il est concerné par les caractéristiques de base de l'objet: ce qu'il a et ce qu'il peut faire. Ainsi, les objets qui héritent de la même classe abstraite partagent les caractéristiques de base (généralisation).
  • L'interface est orientée fonctionnalité . Il définit les fonctionnalités qu'un objet devrait avoir. Quel que soit l'objet, tant qu'il peut faire ces fonctionnalités, qui sont définies dans l'interface, ça va. Il ignore tout le reste. Un objet / classe peut contenir plusieurs (groupes de) fonctionnalités; il est donc possible qu'une classe implémente plusieurs interfaces.

Lorsque vous souhaitez fournir un comportement polymorphe dans une hiérarchie d'héritage, utilisez des classes abstraites.

Lorsque vous voulez un comportement polymorphique pour des classes complètement indépendantes, utilisez une interface.


Pas vraiment la réponse à la question originale, mais une fois que vous avez la réponse à la différence entre eux, vous entrez dans le dilemme quand-à-utiliser-chaque: Quand utiliser des interfaces ou des classes abstraites? Quand utiliser les deux?

J'ai une connaissance limitée de la POO, mais voir les interfaces comme un équivalent d'un adjectif grammatical a fonctionné pour moi jusqu'à maintenant (corrigez-moi si cette méthode est fausse!). Par exemple, les noms d'interface sont comme des attributs ou des capacités que vous pouvez donner à une classe, et une classe peut en avoir plusieurs: ISerializable, ICountable, IList, ICacheable, IHappy, ...


Quelques différences importantes:

Sous la forme d'une table:

Comme l'a déclaré Joe de javapapers :

1. La différence principale est que les méthodes d'une interface Java sont implicitement abstraites et ne peuvent avoir d'implémentations. Une classe abstraite Java peut avoir des méthodes d'instance qui implémente un comportement par défaut.

2.Les variables déclarées dans une interface Java sont par défaut finales. Une classe abstraite peut contenir des variables non finales.

3. Les membres d'une interface Java sont publics par défaut. Une classe abstraite Java peut avoir les saveurs habituelles des membres de la classe comme privée, protégée, etc.

Interface 4.Java devrait être mis en œuvre en utilisant le mot-clé "implémente"; Une classe abstraite Java doit être étendue en utilisant le mot clé "extends".

5.Une interface peut étendre une autre interface Java uniquement, une classe abstraite peut étendre une autre classe Java et implémenter plusieurs interfaces Java.

6.Une classe Java peut implémenter plusieurs interfaces mais elle ne peut étendre qu'une seule classe abstraite.

7. L'interface est absolument abstraite et ne peut pas être instanciée. Une classe abstraite Java ne peut pas non plus être instanciée, mais peut être invoquée si un main () existe.

8.En comparaison avec les classes abstraites Java, les interfaces Java sont lentes car elles nécessitent une indirection supplémentaire.


Travaillons à nouveau sur cette question:

La première chose à vous faire savoir est que 1/1 et 1 * 1 ont le même résultat, mais cela ne veut pas dire que la multiplication et la division sont les mêmes. De toute évidence, ils entretiennent de bonnes relations, mais vous êtes tous les deux différents.

Je signalerai les principales différences, et le reste a déjà été expliqué:

Les classes abstraites sont utiles pour modéliser une hiérarchie de classes. À première vue, nous sommes en partie conscients de ce qui doit être construit exactement , mais nous savons ce qu'il faut construire. Et donc vos classes abstraites sont vos classes de base.

Les interfaces sont utiles pour permettre à d'autres hiérarchies ou classes de savoir ce que je suis capable de faire. Et quand vous dites que je suis capable de quelque chose, vous devez avoir cette capacité. Les interfaces le marqueront comme obligatoire pour une classe d'implémenter les mêmes fonctionnalités.


Une explication peut être trouvée ici: http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm

Une classe abstraite est une classe qui n'est que partiellement implémentée par le programmeur. Il peut contenir une ou plusieurs méthodes abstraites. Une méthode abstraite est simplement une définition de fonction qui sert à indiquer au programmeur que la méthode doit être implémentée dans une classe enfant.

Une interface est similaire à une classe abstraite; En effet, les interfaces occupent le même espace de noms que les classes et les classes abstraites. Pour cette raison, vous ne pouvez pas définir une interface avec le même nom qu'une classe. Une interface est une classe entièrement abstraite; aucune de ses méthodes n'est implémentée et au lieu d'une sous-classe de classe, on dit qu'elle implémente cette interface.

Quoi qu'il en soit, je trouve cette explication des interfaces quelque peu confuse. Une définition plus courante est: Une interface définit un contrat que les classes d'implémentation doivent remplir. Une définition d'interface est constituée de signatures de membres publics, sans aucun code d'implémentation.


Une interface contient uniquement la définition / signature de la fonctionnalité, et si nous avons des fonctionnalités communes ainsi que des signatures communes, nous devons utiliser une classe abstraite. En utilisant une classe abstraite, nous pouvons fournir le comportement ainsi que la fonctionnalité à la fois. Un autre développeur héritant de la classe abstraite peut facilement utiliser cette fonctionnalité, car il lui suffit de remplir les blancs.

Pris à partir de:

http://www.dotnetbull.com/2011/11/difference-between-abstract-class-and.html

http://www.dotnetbull.com/2011/11/what-is-abstract-class-in-c-net.html http://www.dotnetbull.com/2011/11/what-is-interface-in-c-net.html


Différences entre la classe abstraite et l'interface au nom de l'implémentation réelle.

Interface : C'est un mot-clé et il est utilisé pour définir le modèle ou l'impression bleue d'un objet et force toutes les sous-classes à suivre le même prototype, comme pour l'implémentation, toutes les sous-classes sont libres d'implémenter la fonctionnalité c'est l'exigence.

Certains des autres cas d'utilisation où nous devrions utiliser l'interface.

Communication entre deux objets externes (intégration de tiers dans notre application) effectuée via Interface ici L'interface fonctionne en tant que contrat.

Classe abstraite: Résumé, c'est un mot-clé et quand on utilise ce mot-clé avant toute classe, il devient alors classe abstraite. Il est principalement utilisé lorsque l'on a besoin de définir le modèle ainsi que certaines fonctionnalités par défaut d'un objet Sous-classes et de cette façon il supprime le code redondant et un cas d'utilisation où nous pouvons utiliser la classe abstraite , comme nous voulons qu'aucune autre classe ne peut directement instancier un objet de la classe, seules les classes dérivées peuvent utiliser la fonctionnalité.

Exemple de classe abstraite:

 public abstract class DesireCar
  {

 //It is an abstract method that defines the prototype.
     public abstract void Color();

  // It is a default implementation of a Wheel method as all the desire cars have the same no. of wheels.   
 // and hence no need to define this in all the sub classes in this way it saves the code duplicasy     

  public void Wheel() {          

               Console.WriteLine("Car has four wheel");
                }
           }


    **Here is the sub classes:**

     public class DesireCar1 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red color Desire car");
            }
        }

        public class DesireCar2 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red white Desire car");
            }
        }

Exemple d'interface:

  public interface IShape
        {
          // Defines the prototype(template) 
            void Draw();
        }


  // All the sub classes follow the same template but implementation can be different.

    public class Circle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Circle");
        }
    }

    public class Rectangle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Rectangle");
        }
    }

An abstract class is a class whose object cannot be created or a class which cannot be instantiated. An abstract method makes a class abstract. An abstract class needs to be inherited in order to override the methods that are declared in the abstract class. No restriction on access specifiers. An abstract class can have constructor and other concrete(non abstarct methods ) methods in them but interface cannot have.

An interface is a blueprint/template of methods.(eg. A house on a paper is given(interface house) and different architects will use their ideas to build it(the classes of architects implementing the house interface) . It is a collection of abstract methods , default methods , static methods , final variables and nested classes. All members will be either final or public , protected and private access specifiers are not allowed.No object creation is allowed. A class has to be made in order to use the implementing interface and also to override the abstract method declared in the interface. An interface is a good example of loose coupling(dynamic polymorphism/dynamic binding) An interface implements polymorphism and abstraction.It tells what to do but how to do is defined by the implementing class. For Eg. There's a car company and it wants that some features to be same for all the car it is manufacturing so for that the company would be making an interface vehicle which will have those features and different classes of car(like Maruti Suzkhi , Maruti 800) will override those features(functions).

Why interface when we already have abstract class? Java supports only multilevel and hierarchal inheritance but with the help of interface we can implement multiple inheritance.


I'd like to add one more difference which makes sense. For example, you have a framework with thousands of lines of code. Now if you want to add a new feature throughout the code using a method enhanceUI(), then it's better to add that method in abstract class rather in interface. Because, if you add this method in an interface then you should implement it in all the implemented class but it's not the case if you add the method in abstract class.


If you have some common methods that can be used by multiple classes go for abstract classes. Else if you want the classes to follow some definite blueprint go for interfaces.

Following examples demonstrate this.

Abstract class in Java:

abstract class animals
{
    // They all love to eat. So let's implement them for everybody
    void eat()
    {
        System.out.println("Eating...");
    }
    // The make different sounds. They will provide their own implementation.
    abstract void sound();
}

class dog extends animals
{
    void sound()
    {
        System.out.println("Woof Woof");
    }
}

class cat extends animals
{
    void sound()
    {
        System.out.println("Meoww");
    }
}

Following is an implementation of interface in Java:

interface Shape
{
    void display();
    double area();
}

class Rectangle implements Shape 
{
    int length, width;
    Rectangle(int length, int width)
    {
        this.length = length;
        this.width = width;
    }
    @Override
    public void display() 
    {
        System.out.println("****\n* *\n* *\n****"); 
    }
    @Override
    public double area() 
    {
        return (double)(length*width);
    }
} 

class Circle implements Shape 
{
    double pi = 3.14;
    int radius;
    Circle(int radius)
    {
        this.radius = radius;
    }
    @Override
    public void display() 
    {
        System.out.println("O"); // :P
    }
    @Override
    public double area() 
    { 
        return (double)((pi*radius*radius)/2);
    }
}

Some Important Key points in a nutshell:

  1. The variables declared in Java interface are by default final. Abstract classes can have non-final variables.

  2. The variables declared in Java interface are by default static. Abstract classes can have non-static variables.

  3. Members of a Java interface are public by default. A Java abstract class can have the usual flavors of class members like private, protected, etc..


Many junior developers make the mistake of thinking of interfaces, abstract and concrete classes as slight variations of the same thing, and choose one of them purely on technical grounds: Do I need multiple inheritance? Do I need some place to put common methods? Do I need to bother with something other than just a concrete class? This is wrong, and hidden in these questions is the main problem: "I" . When you write code for yourself, by yourself, you rarely think of other present or future developers working on or with your code.

Interfaces and abstract classes, although apparently similar from a technical point of view, have completely different meanings and purposes.

Résumé

  1. An interface defines a contract that some implementation will fulfill for you .

  2. An abstract class provides a default behavior that your implementation can reuse.

Alternative summary

  1. An interface is for defining public APIs
  2. An abstract class is for internal use, and for defining SPIs

On the importance of hiding implementation details

A concrete class does the actual work, in a very specific way. For example, an ArrayList uses a contiguous area of memory to store a list of objects in a compact manner which offers fast random access, iteration, and in-place changes, but is terrible at insertions, deletions, and occasionally even additions; meanwhile, a LinkedList uses double-linked nodes to store a list of objects, which instead offers fast iteration, in-place changes, and insertion/deletion/addition, but is terrible at random access. These two types of lists are optimized for different use cases, and it matters a lot how you're going to use them. When you're trying to squeeze performance out of a list that you're heavily interacting with, and when picking the type of list is up to you, you should carefully pick which one you're instantiating.

On the other hand, high level users of a list don't really care how it is actually implemented, and they should be insulated from these details. Let's imagine that Java didn't expose the List interface, but only had a concrete List class that's actually what LinkedList is right now. All Java developers would have tailored their code to fit the implementation details: avoid random access, add a cache to speed up access, or just reimplement ArrayList on their own, although it would be incompatible with all the other code that actually works with List only. That would be terrible... But now imagine that the Java masters actually realize that a linked list is terrible for most actual use cases, and decided to switch over to an array list for their only List class available. This would affect the performance of every Java program in the world, and people wouldn't be happy about it. And the main culprit is that implementation details were available, and the developers assumed that those details are a permanent contract that they can rely on. This is why it's important to hide implementation details, and only define an abstract contract. This is the purpose of an interface: define what kind of input a method accepts, and what kind of output is expected, without exposing all the guts that would tempt programmers to tweak their code to fit the internal details that might change with any future update.

An abstract class is in the middle between interfaces and concrete classes. It is supposed to help implementations share common or boring code. For example, AbstractCollection provides basic implementations for isEmpty based on size is 0, contains as iterate and compare, addAll as repeated add , and so on. This lets implementations focus on the crucial parts that differentiate between them: how to actually store and retrieve data.

APIs versus SPIs

Interfaces are low-cohesion gateways between different parts of code. They allow libraries to exist and evolve without breaking every library user when something changes internally. It's called Application Programming Interface , not Application Programming Classes. On a smaller scale, they also allow multiple developers to collaborate successfully on large scale projects, by separating different modules through well documented interfaces.

Abstract classes are high-cohesion helpers to be used when implementing an interface, assuming some level of implementation details. Alternatively, abstract classes are used for defining SPIs, Service Provider Interfaces.

The difference between an API and an SPI is subtle, but important: for an API, the focus is on who uses it, and for an SPI the focus is on who implements it.

Adding methods to an API is easy, all existing users of the API will still compile. Adding methods to an SPI is hard, since every service provider (concrete implementation) will have to implement the new methods. If interfaces are used to define an SPI, a provider will have to release a new version whenever the SPI contract changes. If abstract classes are used instead, new methods could either be defined in terms of existing abstract methods, or as empty throw not implemented exception stubs, which will at least allow an older version of a service implementation to still compile and run.

A note on Java 8 and default methods

Although Java 8 introduced default methods for interfaces, which makes the line between interfaces and abstract classes even blurrier, this wasn't so that implementations can reuse code, but to make it easier to change interfaces that serve both as an API and as an SPI (or are wrongly used for defining SPIs instead of abstract classes).

Which one to use?

  1. Is the thing supposed to be publicly used by other parts of the code, or by other external code? Add an interface to it to hide the implementation details from the public abstract contract, which is the general behavior of the thing.
  2. Is the thing something that's supposed to have multiple implementations with a lot of code in common? Make both an interface and an abstract, incomplete implementation.
  3. Is there ever going to be only one implementation, and nobody else will use it? Just make it a concrete class.
    1. "ever" is long time, you could play it safe and still add an interface on top of it.

A corollary: the other way around is often wrongly done: when using a thing , always try to use the most generic class/interface that you actually need. In other words, don't declare your variables as ArrayList theList = new ArrayList() , unless you actually have a very strong dependency on it being an array list, and no other type of list would cut it for you. Use List theList = new ArrayList instead, or even Collection theCollection = new ArrayList if the fact that it's a list, and not any other type of collection doesn't actually matter.


To give a simple but clear answer, it helps to set the context : you use both when you do not want to provide full implementations.

The main difference then is an interface has no implementation at all (only methods without a body) while abstract classes can have members and methods with a body as well, ie can be partially implemented.





abstract-class