Comment aurais-je dû expliquer la différence entre une Interface et une classe abstraite?


Dans une de mes interviews, on m'a demandé d'expliquer la différence entre une interface et une classe abstraite .

Voici ma réponse:

Les méthodes d'une interface Java sont implicitement abstraites et ne peut pas avoir d'implémentations. Une classe abstraite Java peut avoir méthodes d'instance qui implémente un comportement par défaut.

Les variables déclarées dans une interface Java sont par défaut définitives. Un classe abstraite peut contenir non-final variable.

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

Une interface Java doit être implémentée en utilisant le mot-clé "implements"; A La classe abstraite Java doit être étendue en utilisant le mot-clé "extends".

Une interface ne peut étendre qu'une autre interface Java, une classe abstraite peut étendre une autre classe Java et implémenter plusieurs interfaces Java.

Une classe Java peut implémenter plusieurs interfaces mais elle ne peut s'étendre que une classe abstraite.

Cependant, l'intervieweur n'était pas satisfait et m'a dit que cette description représentait " une connaissance livresque".

Il m'a demandé une réponse plus pratique, expliquant quand je choisirais une classe abstraite plutôt qu'une interface, en utilisant des exemples pratiques.

Où est-ce que je me suis trompé?

Author: Ravindra babu, 0000-00-00

30 answers

Je vais d'abord vous donner un exemple:

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

Supposons maintenant que vous ayez 3 bases de données dans votre application. Ensuite, chaque implémentation de cette base de données doit définir les 2 méthodes ci-dessus:

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
}

Mais que se passe - t-il si encryptPassword() ne dépend pas de la base de données, et c'est la même chose pour chaque classe? Alors ce qui précède ne serait pas une bonne approche.

Au lieu de cela, considérez cette approche:

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();
}

Maintenant, dans chaque classe enfant, nous n'avons besoin que d'implémenter une méthode - la méthode qui est à la base de données dépendantes.

J'ai fait de mon mieux et j'espère que cela éclaircira vos doutes.

 459
Author: Vimal Bera, 2014-07-11 08:45:16

Rien n'est parfait dans ce monde. Ils s'attendaient peut-être à une approche plus pratique.

, Mais après votre explication, vous pouvez ajouter ces lignes avec une approche légèrement différente.

  1. Les interfaces sont des règles (règles parce que vous devez leur donner une implémentation que vous ne pouvez pas ignorer ou éviter, afin qu'elles soient imposées comme des règles) qui fonctionne comme un document de compréhension commun entre les différentes équipes de développement logiciel.

  2. Les interfaces donnent l'idée de ce qui est à faire, mais pas comment il sera fait. Donc, l'implémentation dépend complètement du développeur en suivant les règles données (signifie signature donnée des méthodes).

  3. Les classes abstraites peuvent contenir des déclarations abstraites, des implémentations concrètes ou les deux.

  4. Les déclarations abstraites sont comme des règles à suivre et les implémentations concrètes sont comme des directives (vous pouvez l'utiliser telle quelle ou vous pouvez l'ignorer en remplaçant et en donnant votre propre implémentation à elle).

  5. De plus, quelles méthodes avec la même signature peuvent changer le comportement dans un contexte différent sont fournies sous forme de déclarations d'interface sous forme de règles à implémenter en conséquence dans des contextes différents.

Edit: Java 8 facilite la définition des méthodes par défaut et statiques dans l'interface.

public interface SomeInterfaceOne {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
    }
}

Maintenant, lorsqu'une classe implémentera SomeInterface, il n'est pas obligatoire de fournir une implémentation pour les méthodes d'interface par défaut.

Si nous avons une autre interface avec les méthodes suivantes:

public interface SomeInterfaceTwo {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
    }

}

Java ne permet pas d'étendre plusieurs classes car il en résulte le"Problème de diamant" où le compilateur n'est pas en mesure de décider quelle méthode de superclasse utiliser. Avec les méthodes par défaut, le problème du diamant se posera également pour les interfaces. Parce que si une classe implémente les deux

SomeInterfaceOne and SomeInterfaceTwo

Et n'implémente pas la méthode par défaut commune, le compilateur ne peut pas décider lequel choisir. Pour éviter ce problème, en java 8, il est obligatoire pour implémenter des méthodes par défaut communes de différentes interfaces. Si une classe implémente les deux interfaces ci-dessus, elle doit fournir une implémentation pour la méthode defaultMethod() sinon le compilateur lancera une erreur de compilation.

 175
Author: Shailesh Saxena, 2018-03-28 06:39:06

Vous avez fait un bon résumé des différences pratiques d'utilisation et de mise en œuvre, mais n'avez rien dit sur la différence de sens.

Une interface est une description du comportement d'une classe d'implémentation. La classe d'implémentation garantit qu'elle aura ces méthodes qui peuvent être utilisées dessus. Il s'agit essentiellement d'un contrat ou d'une promesse que la classe doit faire.

Une classe abstraite est une base pour différentes sous-classes qui partagent un comportement qui n'a pas besoin d'être créé à plusieurs reprises. Les sous-classes doivent compléter le comportement et avoir la possibilité de remplacer le comportement prédéfini (tant qu'il n'est pas défini comme final ou private).

Vous trouverez de bons exemples dans le paquet java.util qui inclut des interfaces comme List et des classes abstraites comme AbstractList qui implémente déjà l'interface. Le documentation officielle décrit le AbstractList comme suit:

Cette classe fournit une implémentation squelettique de l'interface de liste pour minimiser l'effort requis pour implémenter cette interface soutenue par un magasin de données "à accès aléatoire" (tel qu'un tableau).

 131
Author: Daniel Lerps, 2017-02-07 20:30:37

Une interface se compose de variables singleton (public static final) et de méthodes abstraites publiques. Normalement, nous préférons utiliser une interface en temps réel quand on sait quoi faire, mais ne savent pas comment le faire.

Ce concept peut être mieux compris par exemple:

Considérons une classe de paiement. Le paiement peut être fait de plusieurs façons, telles que PayPal, carte de crédit etc. Nous prenons donc normalement le paiement comme interface qui contient une méthode makePayment() et la carte de crédit et PayPal sont les deux classes d'implémentation.

public interface Payment
{
    void makePayment();//by default it is a abstract method
}
public class PayPal implements Payment
{
    public void makePayment()
    {
        //some logic for PayPal payment
        //e.g. Paypal uses username and password for payment
    }
}
public class CreditCard implements Payment
{
    public void makePayment()
    {
        //some logic for CreditCard payment
        //e.g. CreditCard uses card number, date of expiry etc...
    }
}

Dans l'exemple ci-dessus, CreditCard et PayPal sont deux classes /stratégies d'implémentation. Une Interface nous permet également le concept d'héritage multiple en Java qui ne peut pas être accompli par une classe abstraite.

, Nous choisissons une classe abstraite lorsqu'il y a quelques fonctionnalités que nous savons quoi faire, et d'autres fonctionnalités que nous savons comment effectuer.

Prenons l'exemple suivant:

public abstract class Burger
{
    public void packing()
    {
        //some logic for packing a burger
    }
    public abstract void price(); //price is different for different categories of burgers
}
public class VegBerger extends Burger
{
    public void price()
    {
        //set price for a veg burger.
    }
}
public class NonVegBerger extends Burger
{
    public void price()
    {
        //set price for a non-veg burger.
    }
}

Si nous ajouter des méthodes (concrete / abstract) à l'avenir à une classe abstraite donnée, alors la classe d'implémentation n'aura pas besoin de changer son code. Cependant, si nous ajoutons des méthodes dans une interface à l'avenir, nous devons ajouter des implémentations à toutes les classes qui ont implémenté cette interface, sinon des erreurs de compilation se produisent.

Il y a d'autres différences, mais ce sont des différences majeures qui ont peut-être été ce à quoi votre intervieweur s'attendait . J'espère que cela a été utile.

 72
Author: Satya, 2016-09-25 07:06:54

Toutes vos instructions sont valides sauf votre première instruction (après la version Java 8):

Les méthodes d'une interface Java sont implicitement abstraites et ne peuvent pas avoir d'implémentations

À Partir de la documentation page:

Une interface est un type de référence, similaire à une classe, qui ne peut contenir que constantes, signatures de méthode, méthodes par défaut,méthodes statiques et types imbriqués

Les corps de méthode n'existent que pour méthodes par défaut et méthodes statiques.

méthodes par Défaut:

Une interface peut avoir méthodes par défaut, mais sont différentes des méthodes abstraites dans les classes abstraites.

Les méthodes par défaut vous permettent d'ajouter de nouvelles fonctionnalités aux interfaces de vos bibliothèques et d'assurer la compatibilité binaire avec le code écrit pour les anciennes versions de ces interfaces.

Lorsque vous étendez une interface qui contient une méthode par défaut, vous pouvez suivant:

  1. Ne mentionne pas du tout la méthode par défaut, ce qui permet à votre interface étendue d'hériter de la méthode par défaut.
  2. Redéclarer la méthode par défaut, ce qui la rend abstract.
  3. Redéfinit la méthode par défaut, qui la remplace.

Méthodes Statiques:

En plus des méthodes par défaut, vous pouvez définir des méthodes statiques dans les interfaces. (Une méthode statique est une méthode associée à la classe dans laquelle elle est définie plutôt qu'à n'importe laquelle objet. Chaque instance de la classe partage ses méthodes statiques.)

Cela vous permet d'organiser plus facilement les méthodes d'aide dans vos bibliothèques;

Exemple de code de la page de documentation sur interface ayant des méthodes static et default.

import java.time.*;

public interface TimeClient {
    void setTime(int hour, int minute, int second);
    void setDate(int day, int month, int year);
    void setDateAndTime(int day, int month, int year,
                               int hour, int minute, int second);
    LocalDateTime getLocalDateTime();

    static ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +
                "; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }

    default ZonedDateTime getZonedDateTime(String zoneString) {
        return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }
}

Utilisez les directives ci-dessous pour choisir d'utiliser une interface ou une classe abstraite.

Interface:

  1. Pour définir un contrat ( de préférence sans état - je veux dire pas de variables )
  2. Pour lier des classes sans rapport avec a un capacités.
  3. Pour déclarer des variables constantes publiques(état immuable)

classe Abstraite:

  1. Partager le code entre plusieurs classes étroitement liées. Il établit est un relation.

  2. Action commune entre l'état classes associées ( l'état peut être modifié dans le béton cours)

Articles connexes:

Interface vs Classe abstraite (OO général)

Implémente vs étend: Quand utiliser? Quelle est la différence?

En parcourant ces exemples, vous pouvez comprendre que

Les classes non liées peuvent avoir des capacités via l'interface, mais les classes liées modifient le comportement par l'extension des classes de base.

 35
Author: Ravindra babu, 2017-10-02 05:50:37

Différence entre la classe Abstact et l'interface

  1. Classes abstraites par rapport aux interfaces en Java 8
  2. Différence Conceptuelle:

Méthodes par défaut d'interface dans Java 8

  1. Qu'est-ce que la méthode par défaut?
  2. Erreur de compilation ForEach méthode résolue en utilisant la méthode par défaut
  3. Méthode par défaut et Problèmes d'ambiguïté d'héritage multiple
  4. Points importants sur les méthodes par défaut de l'interface java:

Interface Java Méthode statique

  1. Méthode statique d'interface Java, exemple de code, méthode statique vs méthode par défaut
  2. Points importants sur la méthode statique de l'interface java:

Interfaces fonctionnelles Java



Classes abstraites par rapport aux interfaces en Java 8

Les modifications de l'interface Java 8 incluent les méthodes statiques et les méthodes par défaut dans interface. Avant Java 8, nous ne pouvions avoir que des déclarations de méthode dans interface. Mais à partir de Java 8, nous peut avoir des méthodes par défaut et méthodes statiques dans les interfaces.

Après avoir introduit la méthode par défaut, il semble que les interfaces et les classes abstraites sont les mêmes. Cependant, ils sont encore concept différent en Java 8.

La classe abstraite peut définir le constructeur. Ils sont plus structurés et peut avoir un état associé à eux. Tandis qu'à l'inverse, par défaut méthode peut être mis en œuvre que dans les termes de l'appel d'autres méthodes d'interface, sans référence à un particulier de la mise en œuvre du état. Par conséquent, les deux utilisent à des fins différentes et choisissent entre deux dépend vraiment sur le scénario.

Différence Conceptuelle:

Les classes abstraites sont valides pour les implémentations squelettiques (c'est-à-dire partielles) d'interfaces mais ne devraient pas exister sans une interface correspondante.

Ainsi, lorsque les classes abstraites sont effectivement réduites à une faible visibilité, les implémentations squelettiques des interfaces, les méthodes par défaut peuvent-elles supprimer cela comme bien? Décidément: Non! L'implémentation d'interfaces nécessite presque toujours certains ou tous ces outils de construction de classes qui manquent aux méthodes par défaut. Et si une interface ne le fait pas, c'est clairement un cas particulier, qui ne devrait pas vous égarer.

Méthodes par défaut d'interface dans Java 8

Java 8 introduit" Default Method " ou (Defender methods) nouvelle fonctionnalité, qui permet au développeur d'ajouter de nouvelles méthodes aux interfaces sans casser l'implémentation existante de celles-ci Interface. Il offre une flexibilité pour permettre l'implémentation de Interface define qui sera utilisée par défaut dans la situation où une classe concrète ne fournit pas d'implémentation pour cette méthode.

Prenons petit exemple pour comprendre comment cela fonctionne:

public interface OldInterface {
    public void existingMethod();
 
    default public void newDefaultMethod() {
        System.out.println("New default method"
               + " is added in interface");
    }
}

La classe suivante compilera avec succès dans Java JDK 8,

public class OldInterfaceImpl implements OldInterface {
    public void existingMethod() {
     // existing implementation is here…
    }
}

Si vous créez une instance de OldInterfaceImpl:

OldInterfaceImpl obj = new OldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod(); 

Méthode Par Défaut:

Par défaut les méthodes ne sont jamais finales, ne peuvent pas être synchronisées et ne peuvent pas remplacer l'Objet de méthodes. Ils sont toujours publics, ce qui sévèrement limite la capacité d'écrire des méthodes courtes et réutilisables.

Les méthodes par défaut peuvent être fournies à une Interface sans affecter les Classes d'implémentation car elles incluent une implémentation. Si chaque méthode ajoutée dans une Interface définie avec l'implémentation, aucune classe d'implémentation n'est affectée. Une classe d'implémentation peut remplacer l'implémentation par défaut fourni par l'Interface.

Les méthodes par défaut permettent d'ajouter de nouvelles fonctionnalités aux interfaces existantes sans casser l'ancienne implémentation de ces interfaces.

Lorsque nous étendons une interface qui contient une méthode par défaut, nous pouvons effectuer ce qui suit,

  1. remplace Pas la méthode par défaut et héritera de la méthode par défaut.
  2. Remplacer la méthode par défaut similaire aux autres méthodes que nous remplaçons dans sous-classe.
  3. Redéclarer par défaut méthode comme abstraite, qui force la sous-classe à le remplacer.

Erreur de compilation ForEach méthode résolue en utilisant la méthode par défaut

Pour Java 8, les collections JDK ont été étendues et la méthode forEach est ajoutée à la collection entière (qui fonctionne en conjonction avec les lambdas). Avec la manière conventionnelle, le code ressemble à ci-dessous,

public interface Iterable<T> {
    public void forEach(Consumer<? super T> consumer);
}

Puisque ce résultat chaque classe d'implémentation avec des erreurs de compilation par conséquent, une méthode par défaut ajoutée avec un requis mise en œuvre afin que la mise en œuvre existante ne soit pas modifiée.

L'interface Itérable avec la méthode par défaut est ci-dessous,

public interface Iterable<T> {
    public default void forEach(Consumer
                   <? super T> consumer) {
        for (T t : this) {
            consumer.accept(t);
        }
    }
}

Le même mécanisme a été utilisé pour ajouter Stream dans l'interface JDK sans casser les classes d'implémentation.


Méthode par défaut et Problèmes d'Ambiguïté d'héritage multiple

Puisque la classe java peut implémenter plusieurs interfaces et chaque interface peut définir la méthode par défaut avec la même méthode signature, par conséquent, les méthodes héritées peuvent entrer en conflit les unes avec les autres.

Considérons ci-dessous l'exemple,

public interface InterfaceA {  
       default void defaultMethod(){  
           System.out.println("Interface A default method");  
    }  
}
 
public interface InterfaceB {
   default void defaultMethod(){
       System.out.println("Interface B default method");
   }
}
 
public class Impl implements InterfaceA, InterfaceB  {
}

Le code ci-dessus échouera à compiler avec l'erreur suivante,

Java: class Impl hérite des valeurs par défaut non liées pour defaultMethod () de types InterfaceA et InterfaceB

Afin de corriger cette classe, nous devons fournir l'implémentation de la méthode par défaut:

public class Impl implements InterfaceA, InterfaceB {
    public void defaultMethod(){
    }
}

De plus, si nous voulons invoquer l'implémentation par défaut fournie par n'importe quelle interface super plutôt que notre propre implémentation, nous pouvons le faire comme suit,

public class Impl implements InterfaceA, InterfaceB {
    public void defaultMethod(){
        // existing code here..
        InterfaceA.super.defaultMethod();
    }
}

Nous pouvons choisir n'importe quelle implémentation par défaut ou les deux dans le cadre de notre nouvelle méthode.

Points importants sur les méthodes par défaut de l'interface java:

  1. Les méthodes par défaut de l'interface Java nous aideront à étendre les interfaces sans avoir peur de casser les classes d'implémentation.
  2. Les méthodes par défaut de l'interface Java réduisent les différences entre les interfaces et les classes abstraites.
  3. Les méthodes par défaut de l'interface Java 8 nous aideront à éviter les classes d'utilité, telles que toutes les méthodes de classe Collections peuvent être fournies dans les interfaces elles-mêmes.
  4. Les méthodes par défaut de l'interface Java nous aideront à supprimer les classes d'implémentation de base, nous pouvons fournir une implémentation par défaut et les classes d'implémentation peuvent choisir laquelle remplacer.
  5. l'Une des principales raison de l'introduction de méthodes par défaut dans les interfaces est d'améliorer les Collections API en Java 8 pour prendre en charge les expressions lambda.
  6. Si une classe de la hiérarchie a une méthode avec la même signature, les méthodes par défaut deviennent non pertinentes. Une méthode par défaut ne peut pas remplacer une méthode de java.lang.Objet. Le raisonnement est très simple, c'est parce que Object est la classe de base pour toutes les classes java. Donc, même si nous avons des méthodes de classe d'objet définies comme méthodes par défaut dans les interfaces, cela sera inutile car la méthode de classe d'objet sera toujours utilisée. C'est pourquoi, afin d'éviter confusion, nous ne pouvons pas avoir de méthodes par défaut qui remplacent les méthodes de classe d'objet.
  7. Les méthodes par défaut de l'interface Java sont également appelées méthodes Defender ou Méthodes d'extension virtuelle.

Lien de ressource:

  1. Interface avec les méthodes par défaut vs Classe abstraite en Java 8
  2. La classe abstraite par rapport à l'interface dans l'ère JDK 8
  3. Évolution de l'interface via une extension virtuelle les méthodes de

Méthode statique d'interface Java

L'Interface Java Méthode Statique, exemple de code, méthode statique vs méthode par défaut

La méthode statique de l'interface Java est similaire à la méthode par défaut, sauf que nous ne pouvons pas les remplacer dans les classes d'implémentation. Cette fonctionnalité nous aide à éviter les résultats indésirables en cas de mauvaise implémentation dans les classes d'implémentation. Nous allons examiner cela avec un exemple simple.

public interface MyData {

    default void print(String str) {
        if (!isNull(str))
            System.out.println("MyData Print::" + str);
    }

    static boolean isNull(String str) {
        System.out.println("Interface Null Check");

        return str == null ? true : "".equals(str) ? true : false;
    }
}

Voyons maintenant un classe d'implémentation qui a la méthode isNull () avec une mauvaise implémentation.

public class MyDataImpl implements MyData {

    public boolean isNull(String str) {
        System.out.println("Impl Null Check");

        return str == null ? true : false;
    }

    public static void main(String args[]){
        MyDataImpl obj = new MyDataImpl();
        obj.print("");
        obj.isNull("abc");
    }
}

Notez que isNull(String str) est une méthode de classe simple, elle ne remplace pas la méthode d'interface. Par exemple, si nous ajoutons une annotation @Override à la méthode isNull (), cela entraînera une erreur du compilateur.

Maintenant, lorsque nous allons exécuter l'application, nous obtenons la sortie suivante.

Vérification nulle de l'interface

Impl Vérification nulle

, Si nous faisons l'interface méthode de statique à défaut, nous obtiendrons la sortie suivante.

Impl Vérification nulle

Imprimer mes données::

Impl Vérification nulle

La méthode statique de l'interface Java n'est visible que pour les méthodes d'interface, si nous supprimons la méthode isNull() de la classe MyDataImpl, nous ne pourrons pas l'utiliser pour l'objet MyDataImpl. Cependant, comme d'autres méthodes statiques, nous pouvons utiliser des méthodes statiques d'interface en utilisant le nom de classe. Par exemple, une instruction valide sera être:

boolean result = MyData.isNull("abc");

Points importants sur la méthode statique de l'interface java:

  1. La méthode statique de l'interface Java fait partie de l'interface, nous ne pouvons pas l'utiliser pour les objets de classe d'implémentation.
  2. Les méthodes statiques de l'interface Java sont bonnes pour fournir des méthodes utilitaires, par exemple la vérification nulle, le tri de collection, etc.
  3. La méthode statique de l'interface Java nous aide à assurer la sécurité en ne permettant pas aux classes d'implémentation de les remplacer.
  4. Nous ne pouvons pas définir l'interface méthode statique pour les méthodes de classe d'objet, nous obtiendrons l'erreur du compilateur comme "Cette méthode statique ne peut pas cacher la méthode d'instance de l'objet". En effet, ce n'est pas autorisé en java, car Object est la classe de base pour toutes les classes et nous ne pouvons pas avoir une méthode statique de niveau classe et une autre méthode d'instance avec la même signature.
  5. Nous pouvons utiliser des méthodes statiques d'interface java pour supprimer des classes d'utilité telles que des Collections et déplacer toutes ses méthodes statiques vers l'interface correspondante, qui serait facile à trouver et à utiliser.

Interfaces fonctionnelles Java

Avant de conclure le post, je voudrais fournir une brève introduction aux interfaces fonctionnelles. Une interface avec exactement une méthode abstraite est connue sous le nom d'interface fonctionnelle.

Une nouvelle annotation @FunctionalInterface a été introduite pour marquer une interface comme Interface fonctionnelle. @FunctionalInterface l'annotation permet d'éviter l'ajout accidentel de méthodes abstraites dans les interfaces fonctionnelles. C'est facultatif mais bonne pratique pour l'utiliser.

Les interfaces fonctionnelles sont une fonctionnalité attendue depuis longtemps et très recherchée de Java 8 car elle nous permet d'utiliser des expressions lambda pour les instancier. Un nouveau paquet java.util.des fonctions avec un tas d'interfaces fonctionnelles sont ajoutées pour fournir des types cibles pour les expressions lambda et les références de méthodes. Nous examinerons les interfaces fonctionnelles et les expressions lambda dans les prochains articles.

Emplacement de la ressource:

  1. Java 8 Changements d'interface-méthode statique, méthode par défaut
 32
Author: SkyWalker, 2017-05-23 12:26:33

Votre explication semble décente, mais peut-être que vous avez l'air de tout lire dans un manuel? :-/

Ce qui me dérange le plus, c'est à quel point votre exemple était solide? Avez-vous pris la peine d'inclure presque toutes les différences entre abstract et interfaces?

Personnellement, je suggère ce lien: http://mindprod.com/jgloss/interfacevsabstract.html#TABLE

Pour une liste exhaustive des différences..

J'espère que cela vous aidera, vous et tous les autres lecteurs dans leurs futurs entretiens

 21
Author: VictorCreator, 2013-09-13 04:07:24

De nombreux développeurs juniors font l'erreur de penser les interfaces, les classes abstraites et concrètes comme de légères variations de la même chose, et choisissent l'une d'entre elles uniquement pour des raisons techniques: Ai-je besoin d'un héritage multiple? Ai-je besoin d'un endroit pour mettre des méthodes communes? Ai-je besoin de m'embêter avec autre chose qu'une simple classe concrète? C'est faux, et caché dans ces questions est le problème principal: "I". Lorsque vous écrivez du code pour vous-même, par vous-même, vous avez rarement pensez à d'autres développeurs présents ou futurs travaillant sur ou avec votre code.

Les interfaces et les classes abstraites, bien qu'apparemment similaires d'un point de vue technique, ont des significations et des objectifs complètement différents.

Résumé

  1. Une interface définit un contrat qu'une implémentation remplira pour vous .

  2. Une classe abstraite fournit un comportement par défaut que votre mise en œuvre pouvez réutiliser.

Ces deux points ci-dessus sont ce que je recherche lors de l'entrevue, et est un résumé assez compact. Lire la suite pour plus de détails.

Résumé alternatif

  1. Une interface est pour définir les API publiques
  2. Une classe abstraite est à usage interne, et pour définir SPIs

Par exemple

Pour le dire autrement: Une classe concrète fait le travail réel, d'une manière très spécifique. Par exemple, un ArrayList utilise un zone de mémoire pour stocker une liste d'objets de manière compacte qui offre un accès aléatoire rapide, une itération et des modifications sur place, mais qui est terrible pour les insertions, les suppressions et parfois même les ajouts; pendant ce temps, un LinkedList utilise des nœuds double-liés pour stocker une liste d'objets, qui offre plutôt une itération rapide, des modifications Ces deux types de listes sont optimisés pour différents cas d'utilisation, et la façon dont vous allez importe beaucoup pour les utiliser. Lorsque vous essayez d'extraire les performances d'une liste avec laquelle vous interagissez fortement, et lorsque vous choisissez le type de liste, vous devez choisir soigneusement celui que vous instanciez.

D'autre part, les utilisateurs de haut niveau d'une liste ne se soucient pas vraiment de la façon dont elle est réellement mise en œuvre, et ils devraient être isolés de ces détails. Imaginons que Java n'a pas exposé l'interface List, mais n'avait qu'une classe concrète List qui est en fait ce que LinkedList est droit maintenant. Tous les développeurs Java auraient adapté leur code pour s'adapter aux détails de l'implémentation: éviter l'accès aléatoire, ajouter un cache pour accélérer l'accès, ou simplement réimplémenter ArrayList par eux-mêmes, bien que ce soit incompatible avec tous les autres codes qui fonctionnent uniquement avec List. Ce serait terrible... Mais maintenant, imaginez que les maîtres Java se rendent compte qu'une liste chaînée est terrible pour la plupart des cas d'utilisation réels, et ont décidé de passer à une liste de tableaux pour leur seule classe List disponible. Cela affecterait les performances de tous les programmes Java dans le monde, et les gens ne seraient pas heureux à ce sujet. Et le principal coupable est que les détails de mise en œuvre étaient disponibles, et les développeurs ont supposé que ces détails sont un contrat permanent sur lequel ils peuvent compter. C'est pourquoi il est important de masquer les détails de l'implémentation et de définir uniquement un contrat abstrait. C'est le but d'une interface: définir quel type d'entrée une méthode accepte, et quel type de sortie est attendu, sans exposer tous les tripes qui tenteraient les programmeurs de modifier leur code pour s'adapter aux détails internes qui pourraient changer avec toute mise à jour future.

Une classe abstraite est au milieu entre les interfaces et les classes concrètes. Il est censé aider les implémentations à partager du code commun ou ennuyeux. Par exemple, AbstractCollection fournit des implémentations de base pour isEmpty basées sur la taille est 0, contains comme itérer et comparer, addAll comme répété add, et ainsi de suite. Cela permet aux implémentations de se concentrer sur le parties cruciales qui les différencient: comment stocker et récupérer des données.

Une autre perspective: APIs contre SPIs

Les interfaces sont des passerelles à faible cohésion entre différentes parties du code. Ils permettent aux bibliothèques d'exister et d'évoluer sans casser chaque utilisateur de bibliothèque lorsque quelque chose change en interne. Il s'appelle Programmation d'applications Interface, pas de Classes de Programmation d'Application. À plus petite échelle, ils permettent également plusieurs les développeurs collaborent avec succès sur des projets à grande échelle, en séparant différents modules via des interfaces bien documentées.

Les classes abstraites sont des aides à haute cohésion à utiliser lors de l'implémentation d'une interface, en supposant un certain niveau de détails d'implémentation. Alternativement, des classes abstraites sont utilisées pour définir SPIs, Interfaces de fournisseur de services.

La différence entre une API et un SPI est subtile, mais importante: pour une API, l'accent est mis sur qui utilise, et pour un SPI l'accent est mis sur qui implémente il.

Ajouter des méthodes à une API est facile, tous les utilisateurs existants de l'API compileront toujours. Ajouter des méthodes à un SPI est difficile, car chaque fournisseur de services (implémentation concrète) devra implémenter les nouvelles méthodes. Si des interfaces sont utilisées pour définir un SPI, un fournisseur devra publier une nouvelle version chaque fois que le contrat SPI changera. Si des classes abstraites sont utilisées à la place, de nouvelles méthodes pourraient être défini en termes de méthodes abstraites existantes, ou comme des talons vides throw not implemented exception, qui permettront au moins à une ancienne version d'une implémentation de service de continuer à compiler et à s'exécuter.

Une note sur Java 8 et les méthodes par défaut

Bien que Java 8 ait introduit des méthodes par défaut pour les interfaces, ce qui rend la ligne entre les interfaces et les classes abstraites encore plus floue, ce n'était pas pour que les implémentations puissent réutiliser le code, mais pour faciliter le changement d'interfaces qui servent à la fois d'API et de SPI (ou sont utilisés à tort pour définir SPIs au lieu de classes abstraites).

"Connaissance du livre"

Les détails techniques fournis dans la réponse du PO sont considérés comme des "connaissances du livre" parce que c'est généralement l'approche utilisée à l'école et dans la plupart des livres technologiques sur une langue: ce qu'estune chose, pas comment l'utiliser dans la pratique, en particulier dans les applications à grande échelle.

Voici une analogie: supposé que la question était:

Qu'est-ce que mieux louer pour la nuit de bal, une voiture ou une chambre d'hôtel?

La réponse technique ressemble à:

Eh Bien, dans une voiture, vous pouvez le faire plus tôt, mais dans une chambre d'hôtel, vous pouvez le faire plus confortablement. D'autre part, la chambre d'hôtel est dans un seul endroit, alors que dans la voiture, vous pouvez le faire dans plus d'endroits, comme, disons que vous pouvez aller sur le point de vista pour une belle vue, ou dans un drive-in theater, ou de nombreux autres endroits, ou même dans plus d'un endroit. En outre, la chambre d'hôtel dispose d'un douche.

C'est tout vrai, mais manque complètement les points qu'ils sont deux choses complètement différentes, et les deux peuvent être utilisés en même temps à des fins différentes, et l'aspect "faire" n'est pas la chose la plus importante à propos de l'une ou l'autre des deux options. La réponse manque de perspective, elle montre une façon de penser immature, tout en présentant correctement les vrais "faits".

 18
Author: Sergiu Dumitriu, 2016-06-19 14:58:37

Une interface est un "contrat" où la classe qui implémente le contrat promet d'implémenter les méthodes. Un exemple où je devais écrire une interface au lieu d'une classe était lorsque je mettais à niveau un jeu de 2D à 3D. Je devais créer une interface pour partager des classes entre la version 2D et la version 3D du jeu.

package adventure;
import java.awt.*;
public interface Playable {
    public void playSound(String s);
    public Image loadPicture(String s);    
}

Ensuite, je peux implémenter les méthodes basées sur l'environnement, tout en étant capable d'appeler ces méthodes à partir d'un objet qui ne sait pas quelle version du jeu qui est en cours de chargement.

public class Adventure extends JFrame implements Playable

public class Dungeon3D extends SimpleApplication implements Playable

public class Main extends SimpleApplication implements AnimEventListener, ActionListener, Playable

Généralement, dans le jeu, le monde peut être une classe abstraite qui effectue des méthodes sur le jeu:

public abstract class World...

    public Playable owner;

    public Playable getOwner() {
        return owner;
    }

    public void setOwner(Playable owner) {
        this.owner = owner;
    }
 9
Author: Niklas Rosencrantz, 2017-06-20 12:22:45

Les classes Abstraites sont destinés à être héréditaire, et lorsqu'une classe hérite d'une autre cela signifie qu'il existe une relation forte entre les 2 classes. Avec une interface d'autre part, la relation entre l'interface et la classe implémentant l'interface n'est pas nécessairement très fort. Nous pouvons donc résumer ce premier point en disant qu'une classe abstraite serait plus appropriée lorsqu'il existe une forte relation entre la classe abstraite et les classes qui sera en découlent. Encore une fois, c'est parce qu'une classe abstraite est très étroitement liée à l'héritage, ce qui implique une forte relation. Mais, avec les interfaces, il n'est pas nécessaire d'avoir une relation forte entre l'interface et les classes qui implémentent l'interface. L'interface Java peut étendre plusieurs interfaces la classe Java peut également implémenter plusieurs interfaces, ce qui signifie que l'interface peut fournir plus de prise en charge du polymorphisme que la classe abstraite . En étendant la classe abstraite, une classe ne peut participer à une hiérarchie de type, mais en utilisant l'interface, il peut faire partie de plusieurs hiérarchies de type.

Pour implémenter l'interface en Java, jusqu'à ce que votre classe soit abstraite, vous devez fournir l'implémentation de toutes les méthodes, ce qui est très douloureux. D'autre part, la classe abstraite peut vous aider dans ce cas en fournissant une implémentation par défaut.

 6
Author: Raji, 2014-07-02 18:19:28

Qu'en est-il de penser de la manière suivante:

  • Une relation entre une classe et une classe abstraite est de type "est-un"
  • Une relation entre une classe et une interface est de type "est-un"

Donc, quand vous avez une classe abstraite Mammals, une sous-classe Human, et une interface Driving, alors vous pouvez dire

  • chaque Humain est un Mammifère
  • chaque Humain a-une Conduite (comportement)

Ma suggestion est que la phrase de la connaissance du livre indique que il voulait entendre la différence sémantique entre les deux (comme d'autres ici déjà suggéré).

 6
Author: akohout, 2014-11-13 09:55:46

Les classes abstraites ne sont pas de l'abstraction pure bcz sa collection de méthodes concrètes(implémentées) ainsi que de méthodes non implémentées. Mais Les interfaces sont de l'abstraction pure bcz il n'y a que des méthodes non implémentées pas des méthodes concrètes.

Pourquoi des cours abstraits?

  1. Si l'utilisateur veut écrire une fonctionnalité commune pour tous les objets.
  2. Les classes abstraites sont le meilleur choix pour la réimplémentation à l'avenir pour ajouter plus de fonctionnalités sans affecter la fin utilisateur.

Pourquoi les interfaces?

  1. Si l'utilisateur veut écrire une fonctionnalité différente, ce serait une fonctionnalité différente sur les objets.
  2. Les interfaces sont le meilleur choix qui, sinon, doivent modifier les exigences une fois l'interface publiée.
 6
Author: Sarfaraz Ahamad, 2016-09-03 23:44:22

La principale différence que j'ai observée était que la classe abstraite nous fournit un comportement commun déjà implémenté et que les sous-classes n'ont besoin que d'implémenter des fonctionnalités spécifiques qui leur correspondent. où comme pour une interface ne spécifiera que les tâches à effectuer et aucune implémentation ne sera donnée par interface. Je peux dire qu'il spécifie le contrat entre lui-même et les classes implémentées.

 5
Author: SONIYA GAVI, 2014-01-29 08:42:37

Une interface est comme un ensemble de gènes qui sont publiquement documentés pour avoir une sorte d'effet: Un test ADN me dira si je les ai - et si je le fais, je peux publiquement faire savoir que je suis un "porteur" et qu'une partie de mon comportement ou de mon état s'y conformera. (Mais bien sûr, je peux avoir beaucoup d'autres gènes qui fournissent des traits en dehors de cette portée.)

Une classe abstraite est comme l'ancêtre mort d'une espèce unique (*): Elle ne peut pas être ramenée à la vie mais un descendant vivant (c'est-à-dire non abstrait) hérite de tous ses gènes.

(*) Pour étirer cette métaphore, disons que tous les membres de l'espèce vivent au même âge. Cela signifie que tous les ancêtres d'un ancêtre mort doivent également être morts-et de même, tous les descendants d'un ancêtre vivant doivent être vivants.

 5
Author: Steve Chambers, 2016-06-22 12:36:21

Je fais des interviews pour le travail et je regarderais défavorablement votre réponse aussi (désolé mais je suis très honnête). Il semble que vous ayez lu la différence et révisé une réponse, mais vous ne l'avez peut-être jamais utilisée dans la pratique.

Une bonne explication de la raison pour laquelle vous utiliseriez chacun peut être bien meilleure que d'avoir une explication précise de la différence. Les employeurs ultimatley veulent que les programmateurs fassent des choses qui ne les connaissent pas, ce qui peut être difficile à démontrer lors d'une entrevue. La réponse que vous avez donné ce serait bien si vous postulez pour un travail technique ou basé sur la documentation mais pas un rôle de développeur.

Bonne chance avec des interviews à l'avenir.

Aussi ma réponse à cette question est plus sur la technique d'entrevue plutôt que le matériel technique que vous avez fourni. Peut-être envisager de lire à ce sujet. https://workplace.stackexchange.com/ peut être un excellent endroit pour ce genre de chose.

 4
Author: Adrian Blackburn, 2017-04-13 12:48:41

Une interface est purement abstraite. nous n'avons aucun code d'implémentation dans l'interface.

La classe abstraite contient à la fois des méthodes et son implémentation.

Cliquez ici pour voir le tutoriel sur les interfaces et les classes abstraites

 3
Author: user2822053, 2013-10-08 09:38:11

La principale différence que j'ai observée était que la classe abstraite nous fournit un comportement commun déjà implémenté et que les sous-classes n'ont besoin que d'implémenter des fonctionnalités spécifiques qui leur correspondent. où comme pour une interface ne spécifiera que les tâches à effectuer et aucune implémentation ne sera donnée par interface. Je peux dire qu'il spécifie le contrat entre lui-même et les classes implémentées.

 3
Author: , 2013-10-28 04:56:04

Même moi, j'ai fait face à la même question dans plusieurs interviews et croyez-moi, cela rend votre temps misérable pour convaincre l'intervieweur. Si j'inhérent toutes les réponses d'en haut, je dois ajouter un autre point clé pour le rendre plus convaincant et utiliser OO à son meilleur

Dans le cas où vous ne prévoyez aucune modification dans les règles , pour que la sous-classe soit suivie, dans un avenir long, optez pour l'interface, car vous ne pourrez pas la modifier et si vous le faites, vous devez allez pour les changements dans toutes les autres sous-classes, alors que, si vous pensez, vous voulez réutiliser la fonctionnalité, définir des règles et aussi la rendre ouverte à la modification, allez pour la classe abstraite.

Pensez de cette façon, vous aviez utilisé un service consommable ou vous aviez fourni du code à world et Vous avez une chance de modifier quelque chose, supposons un contrôle de sécurité Et si je suis un consommateur du code et un matin après une mise à jour, je trouve toutes les marques de lecture dans mon Eclipse, entières l'application est en panne. Donc, pour éviter de tels cauchemars, utilisez Abstract over Interfaces

Je pense que cela pourrait convaincre l'intervieweur dans une certaine mesure...Bonnes Interviews À Venir.

 3
Author: vinod bazari, 2015-03-06 18:21:12

Vous choisissez Interface en Java pour éviter le problème de Diamant dans l'héritage multiple.

Si vous voulez que toutes vos méthodes soient implémentées par votre client, vous optez pour interface. Cela signifie que vous concevez l'ensemble de l'application chez abstract.

Vous choisissez la classe abstraite si vous savez déjà ce qui est en commun. Par exemple, Prenez une classe abstraite Car. Au niveau supérieur, vous implémentez les méthodes de voiture courantes comme calculateRPM(). C'est une méthode courante et vous laissez le client implémenter son propre comportement comme
calculateMaxSpeed() etc. Vous auriez probablement expliqué en donnant quelques exemples en temps réel que vous avez rencontrés dans votre travail quotidien.

 3
Author: MaheshVarma, 2016-06-20 02:18:12

Lorsque j'essaie de partager un comportement entre 2 classes étroitement liées, je crée une classe abstraite qui contient le comportement commun et sert de parent aux deux classes.

Lorsque j'essaie de définir un Type, une liste de méthodes qu'un utilisateur de mon objet peut appeler de manière fiable, je crée une interface.

Par exemple, je ne créerais jamais une classe abstraite avec 1 sous-classe concrète car les classes abstraites concernent le comportement de partage. Mais je pourrais très eh bien, créez une interface avec une seule implémentation. L'utilisateur de mon code ne saura pas qu'il n'y a qu'une seule implémentation. En effet, dans une future version, il peut y avoir plusieurs implémentations, qui sont toutes des sous-classes d'une nouvelle classe abstraite qui n'existait même pas lorsque j'ai créé l'interface.

Cela aurait pu sembler un peu trop bookish aussi (bien que je ne l'ai jamais vu mettre de cette façon partout où je me souviens). Si l'intervieweur (ou le PO) voulait vraiment plus de mon personnel expérience à ce sujet, j'aurais été prêt avec des anecdotes d'une interface a évolué par nécessité et vice versa.

Encore une chose. Java 8 vous permet maintenant de mettre du code par défaut dans une interface, brouillant encore la ligne entre les interfaces et les classes abstraites. Mais d'après ce que j'ai vu, cette fonctionnalité est surutilisée même par les fabricants des bibliothèques Java Core. Cette fonctionnalité a été ajoutée, et à juste titre, pour permettre d'étendre une interface sans créer de binaire incompatibilité. Mais si vous créez un tout nouveau type en définissant une interface, alors l'interface devrait être JUSTE une interface. Si vous souhaitez également fournir du code commun, créez par tous les moyens une classe d'aide (abstraite ou concrète). Ne pas encombrer votre interface dès le début avec des fonctionnalités que vous voudrez peut-être modifier.

 2
Author: Teto, 2016-06-17 04:28:28

D'après ce que je comprends, une interface, qui est composée de variables finales et de méthodes sans implémentations, est implémentée par une classe pour obtenir un groupe de méthodes ou de méthodes qui sont liées les unes aux autres. D'autre part, une classe abstraite, qui peut contenir des variables et des méthodes non finales avec des implémentations, est généralement utilisée comme guide ou comme superclasse dont toutes les classes liées ou similaires héritent. En d'autres termes, une classe abstraite contient tous les méthodes / variables partagées par toutes ses sous-classes.

 1
Author: Marz, 2013-10-14 12:41:56

Dans la classe abstraite, vous pouvez écrire l'implémentation par défaut des méthodes! Mais dans l'interface, vous ne pouvez pas. Pour l'essentiel, Dans l'interface, il existe des méthodes virtuelles pures qui doivent être implémentées par la classe qui implémente l'interface.

 1
Author: dg_no_9, 2013-10-28 05:00:56

Hmm maintenant, les gens sont hungery approche pratique, vous avez tout à fait raison, mais la plupart des regards interviewer selon leur exigence actuelle et veulent une approche pratique.

Après avoir terminé votre réponse, vous devriez sauter sur l'exemple:

Résumé:

Par exemple, nous avons une fonction de salaire qui a un paramètre commun à tous les employés. ensuite nous pouvons avoir une classe abstraite appelée CTC avec un corps de méthode partiellement défini et elle sera étendue par tout type d'employé et se faire racheter selon leurs beefits supplémentaires. Pour la fonctonalité commune.

public abstract class CTC {

    public int salary(int hra, int da, int extra)
    {
        int total;
        total = hra+da+extra;
        //incentive for specific performing employee
        //total = hra+da+extra+incentive;
        return total;
    }
}

class Manger extends CTC
{
}


class CEO extends CTC
{
}

class Developer extends CTC
{   
}

Interface

L'interface en java permet d'avoir des fonctionnalités interfcae sans étendre celle-ci et vous devez être clair avec l'implémentation de la signature des fonctionnalités que vous souhaitez introduire dans votre application. cela vous forcera à avoir une définition. Pour différentes fonctionnalités. interface publique EmployeType {

    public String typeOfEmployee();
}

class ContarctOne implements EmployeType
{

    @Override
    public String typeOfEmployee() {
        return "contract";
    }

}

class PermanentOne implements EmployeType
{

    @Override
    public String typeOfEmployee() {
        return "permanent";
    }

}

Vous pouvez avoir une telle activité forcée avec abstract classe trop défini par methgos comme un abstrait, maintenant une classe tha étend la classe abstraite remin, abstraite jusqu'à ce qu'il ignorer que la fonction abstraite.

 1
Author: RTA, 2014-01-09 06:44:24

Oui, vos réponses étaient techniquement correctes, mais là où vous vous êtes trompé, vous ne les avez pas montrées, vous comprenez les avantages et les inconvénients du choix de l'un plutôt que de l'autre. De plus, ils étaient probablement préoccupés / paniqués par la compatibilité de leur base de code avec les mises à niveau à l'avenir. Ce type de réponse a peut-être aidé (en plus de ce que vous avez dit):

"Choisir une classe abstraite sur une classe d'Interface dépend de ce que nous projet l'avenir du code sera.

Les classes abstraites permettent une meilleure compatibilité directe car vous pouvez continuer à ajouter un comportement à une classe abstraite bien dans le futur sans casser votre code existant --> ce n'est pas possible avec un L'Interface De La Classe.

D'autre part, les classes d'interface sont plus flexibles qu'Abstraites Classe. En effet, ils peuvent implémenter plusieurs interfaces. Le la chose est Java n'a pas plusieurs héritages donc en utilisant abstract les classes ne laisseront pas vous utilisez toute autre structure de hiérarchie de classe...

Donc, à la fin, une bonne règle générale est: Préférez utiliser l'interface Classes lorsqu'il n'y a pas d'implémentations existantes/par défaut dans votre codebase. Et, utilisez des classes abstraites pour préserver la compatibilité si vous sachez que vous mettrez à jour votre classe à l'avenir."

Bonne chance pour votre prochaine entrevue!

 1
Author: Jaxian, 2016-06-19 15:53:18

Je vais essayer de répondre en utilisant un scénario pratique pour montrer la distinction entre les deux.

Les interfaces sont livrées avec une charge utile nulle, c'est-à-dire qu'aucun état ne doit être maintenu et sont donc un meilleur choix pour simplement associer un contrat (capacité) à une classe.

Par exemple, disons que j'ai une classe de tâches qui effectue une action, maintenant pour exécuter une tâche dans un thread séparé, je n'ai pas vraiment besoin d'étendre la classe de Threads plutôt le meilleur choix est de faire en sorte que la tâche implémente une interface exécutable (c'est-à-dire implémenter sa méthode run ()), puis passez l'objet de cette classe de tâche à une instance de Thread et appelez sa méthode start ().

Maintenant, vous pouvez demander si Runnable était une classe abstraite?

Bien techniquement c'était possible mais en termes de conception cela aurait été un mauvais choix raison étant:

  • Runnable n'a aucun état qui lui est associé et il n'en "offre" aucun implémentation par défaut de la méthode run ()
  • La tâche devrait l'étendre donc elle ne pourrait pas s'étendre toute autre classe
  • Task n'a rien à offrir comme spécialisation à la classe Runnable, tout ce dont elle a besoin est de remplacer la méthode run ()

En d'autres termes, la classe Task avait besoin d'une capacité à exécuter dans un thread, ce qu'elle a réalisé en implémentant des versets d'interface exécutables étendant la classe Thread qui en ferait un thread.

Mettez simplement l'interface us pour définir une capacité( contrat), tout en utilisant un classe abstraite pour définir l'implémentation squelette (commune / partielle) de il.

Avertissement: exemple stupide suit, essayez de ne pas juger :-P

interface Forgiver {
    void forgive();
}

abstract class GodLike implements Forgiver {
    abstract void forget();
    final void forgive() {
        forget();
    }
}

Maintenant, on vous a donné le choix d'être semblable à Dieu, mais vous pouvez choisir d'être Pardonneur seulement (c'est-à-dire pas semblable à Dieu) et faire:

class HumanLike implements Forgiver {
    void forgive() {
       // forgive but remember    
    }
}

Ou vous pouvez choisir d'être semblable à Dieu et de faire:

class AngelLike extends GodLike {
    void forget() {
       // forget to forgive     
    }
}

PS avec l'interface java 8 peut également avoir des méthodes statiques par défaut (implémentation remplaçable) et donc la différence entre l'interface b/w et la classe abstraite est encore plus réduite.

 1
Author: sactiw, 2017-05-04 20:59:32

Presque tout semble déjà couvert ici.. Ajouter juste un point de plus sur l'implémentation pratique de la classe abstract:

abstract le mot clé est également utilisé juste empêcher une classe d'être instanciée. Si vous avez une classe concrète que vous ne voulez pas instancier - Faites-la abstract.

 1
Author: Blade, 2017-05-29 16:56:03

Votre réponse est ok, mais je pense qu'il cherchait ce genre de réponse:

Classe Abstraite

  • La classe abstraite peut avoir des méthodes abstraites et non abstraites.
  • La classe abstraite ne prend pas en charge l'héritage multiple.
  • La classe abstraite peut avoir des variables finales, non finales, statiques et non statiques.
  • La classe abstraite peut fournir l'implémentation de l'interface.

Interface

  • Interface peut avoir par défaut, statique et méthodes abstraites.
  • L'interface prend en charge l'héritage multiple.
  • L'interface n'a que des variables statiques et finales.
  • L'interface ne peut pas fournir l'implémentation de la classe abstraite.
 1
Author: user1913615, 2017-10-23 12:01:55

D'après ce que je comprends et comment je m'approche,

L'interface est comme une spécification / contrat, toute classe qui implémente une classe d'interface doit implémenter toutes les méthodes définies dans la classe abstraite (sauf les méthodes par défaut (introduites dans java 8))

Alors que je définis un résumé de classe quand je connais l'implémentation requise pour certaines méthodes de la classe et certaines méthodes, je ne sais toujours pas quelle sera l'implémentation (nous pourrions connaître la signature de la fonction mais pas le application). Je le fais pour que plus tard dans la partie du développement quand je sais comment ces méthodes doivent être implémentées, je puisse simplement étendre cette classe abstraite et implémenter ces méthodes.

Remarque: Vous ne pouvez pas avoir de corps de fonction dans les méthodes d'interface à moins que la méthode ne soit statique ou par défaut.

 0
Author: Akash Lodha, 2016-06-17 09:13:06

Je crois que ce que l'intervieweur essayait d'obtenir était probablement la différence entre l'interface et la mise en œuvre.

L'interface - pas d'une interface Java, mais "interface" en termes plus généraux, - un module de code est, fondamentalement, le contrat conclu avec le code client qui utilise l'interface.

L'implémentation d'un module de code est le code interne qui fait fonctionner le module. Souvent, vous pouvez implémenter une interface particulière de plus d'une manière différente, et même changer l'implémentation sans que le code client soit même au courant du changement.

Une interface Java ne doit être utilisée qu'en tant qu'interface au sens générique ci-dessus, pour définir le comportement de la classe au profit du code client utilisant la classe, sans spécifier d'implémentation. Ainsi, une interface inclut des signatures de méthode - les noms, les types de retour et les listes d'arguments - pour les méthodes censées être appelées par le code client, et devrait en principe avoir beaucoup de Javadoc pour chaque méthode en décrivant ce que la méthode n'. La raison la plus convaincante pour utiliser une interface est si vous prévoyez d'avoir plusieurs implémentations différentes de l'interface, peut-être en sélectionnant une implémentation en fonction de la configuration du déploiement.

Une classe abstraite Java, en revanche, fournit une implémentation partielle de la classe, plutôt que d'avoir pour but principal de spécifier une interface. Il doit être utilisé lorsque plusieurs classes partagent du code, mais lorsque les sous-classes sont également censées fournir une partie de la mise en œuvre. Cela permet au code partagé d'apparaître à un seul endroit - la classe abstraite - tout en précisant que certaines parties de l'implémentation ne sont pas présentes dans la classe abstraite et devraient être fournies par des sous-classes.

 0
Author: Warren Dew, 2016-06-20 01:52:22

Votre réponse est juste mais l'intervieweur a besoin de vous pour différencier selon la perspective de l'ingénierie logicielle et non selon les détails de Java.

Mots Simples:

Une Interface est comme l'interface d'un magasin tout ce qui y est affiché devrait être là dans le magasin, donc toute méthode de l'Interface doit y être implémentée dans la classe concrete. Maintenant, que se passe-t-il si certaines classes partagent des méthodes exactes et varient dans d'autres. Supposons que l'interface concerne un magasin qui contient deux choses et supposons que nous ayons deux magasins contiennent tous deux du matériel de sport, mais l'un a des vêtements en plus et l'autre a des chaussures en plus. Donc, ce que vous faites, c'est créer une classe abstraite pour le Sport qui implémente la méthode Sportive et laisse l'autre méthode non appliquée. La classe abstraite ici signifie que cette boutique n'existe pas elle-même mais qu'elle est la base pour d'autres classes/boutiques. De cette façon, vous organisez le code, évitez les erreurs de réplication du code, unifiez le code et garantissez sa réutilisation en certains autres de la classe.

 0
Author: Mosab Shaheen, 2016-11-27 18:06:07