11
votes

Interface VS de classe 100% abstraite

Y a-t-il une raison d'utiliser une classe 100% abstraite et non une interface? Pouvez-vous me donner un bon exemple quand utiliser les deux afin que je puisse saisir le concept un peu?

mise à jour: Catégorie 100% abstraite -> Classe abstraite avec seulement des méthodes abstraites. Je suis curieux s'il y a des différences entre PHP et Java concernant cet aspect.

mise à jour2: Même si je comprends la plupart des raisons, je suis plus intéressé par les «forts> conceptuels conceptuels plus que des raisons techniques.


3 commentaires

Comment définir «100% de classe abstraite»?


Java ou PHP? laquelle est-ce?


Je pense qu'il désigne une classe abstraite avec seulement des méthodes abstraites, aucune implémentation par défaut


7 Réponses :


18
votes

Si par "classe abstraite 100%", vous voulez dire "Classe abstraite sans méthodes concrètes", alors je peux penser à une raison: visibilité.

Vous pouvez définir une méthode abstraite à protéger et, partant, ne faisant pas partie de l'API publique de la classe. Cependant, cela semble être un design étrange.

Une autre chose qui me suis venu à mon esprit est lorsque vous vous attendez à ajouter des fonctionnalités courantes à la classe de base - c'est-à-dire que cela devrait avoir des méthodes d'utilité partagées par tous les accompagnateurs, mais ces méthodes ne sont pas implémentées.

Une autre chose - variables d'instance. Vous pouvez avoir des variables d'instance héritables dans la classe abstraite.


5 commentaires

Dans une classe 100% abstraite, vous pouvez également définir des variables non constantes qui peuvent être hébergées. Ce n'est pas possible avec des interfaces.


@Benoit Courtine exactement. J'ajoutais cela pendant que vous avez commenté :) merci quand même.


Une autre chose est des constructeurs ... ce n'est pas non plus possible dans les interfaces


Les méthodes statiques ne contribuent pas beaucoup, ils peuvent être dans n'importe quelle classe. Mais oui, ils comptent. :)


@Bozho, re: méthodes statiques. Mon point était que puisque vous ne pouvez pas les placer dans l'interface, vous devez faire une autre classe juste pour les mettre quelque part. C'est pourquoi nous avons la classe Helper Collections en plus de l'interface de collecte.



0
votes

La classe abstraite 100% n'est pas une bonne idée. Pour une structure commune des classes d'enfants utilise une interface. Pour les classes similiaires avec les mêmes méthodes et pas les mêmes autres d'autres mieux d'utiliser une classe abstraite.


0 commentaires

2
votes

À côté de la visibilité, une autre raison pourrait être de pouvoir spécifier un certain constructeur que vous souhaitez que toutes les implémentations implémentent ou définissent une certaine propriété. Mais en général, je suis d'accord avec Alexander qu'une classe 100% abstraite n'est pas une bonne idée. Je préférerais une interface dans la plupart des cas, sauf si il y a une très bonne raison de ne pas utiliser une interface.


0 commentaires

1
votes

Je pense personnellement que la différence est conceptuelle plus que technique. Par exemple, ce serait une mauvaise idée d'avoir une interface appelée «humaine» et de les mettre en œuvre sur les hommes et les femmes. Cela aurait plus de sens de rendre l'homme comme classe.

Vous pouvez implémenter plusieurs interfaces et vous devez voir des interfaces en tant que compléments.


3 commentaires

Les hommes et les femmes partagent la fonctionnalité, elles ne sont pas différentes implémentations d'une interface commune. En outre, le concept d'un humain n'est pas défini par les fonctions humains implémenter.


Il serait plus facile pour moi de le comprendre comme une classe au lieu d'une interface. Je peux en fait la visualiser comme un arbre et voir que le mâle et les femmes branchissent de l'homme.


Oui, et Habituellement Il n'y a pas d'homme qui n'est ni homme ni femme, donc la classe de base humain serait abstraite.



11
votes

Le seul cas où une "classe 100% abstraite" peut être avantageuse sur une interface est dans des endroits où la stabilité de l'API est une préoccupation clé.

Si vous écrivez une API où d'autres personnes devraient implémenter votre interface, vous devez vous tenir à l'interface. Vous ne pouvez pas ajouter de méthodes à l'interface plus tard, car cela briserait tous les clients (vous devrez contourner cela en implémentant une deuxième interface et laisser votre code vérifier l'utilisation de l'utilisation avec l'instance de chèque et fournir une relèvement).

Si vous réalisez la même chose avec une classe, vous pouvez ajouter des méthodes (non abstraites) plus tard sans casser le client.


2 commentaires

+1. Ceci est un problème avec les interfaces JDK comme Java.SQL.Connection, où elles ajoutent des méthodes tout le temps, de sorte que les anciennes implémentations ne compilent plus.


Si les interfaces de collecte étaient des classes abstraites «pures», nous n'avions pas besoin de méthodes de défenseur.



1
votes

Je ne suis pas tout à fait sûr de savoir comment répondre à ce conceptuellement, mais dans la pratique, j'utilise des interfaces pour les raisons suivantes:

  • Pour indiquer que différentes classes ont une interface partagée: que vous pouvez les manipuler / les utiliser de la même manière
  • Vous pouvez implémenter plusieurs interfaces, mais n'élargir que une classe

    raisons d'utiliser des classes abstraites:

    • Pour partager la fonctionnalité entre des objets similaires. Par exemple, Porshe911 pourrait prolonger la voiture, écraser quelques méthodes et garder le reste.
    • Pour écrire des cadres que les gens peuvent s'adapter. Par exemple, en laissant quelques méthodes cruciales sans image et écrivant le reste de la classe à être cohérente en interne, vous devez mettre en œuvre ces quelques méthodes. Un exemple serait une classe de menus avec une seule méthode abstraite getMenuitems ()

      Votre exemple de la classe 100% abstrait semble insensé pour moi. Pour autant que je sache, cela en ferait une interface, avec la restriction supplémentaire que vous ne pouvez en avoir qu'un.


0 commentaires

0
votes

Voici un exemple simple qui peut être réalisé par interface uniquement.

interface P {
    void p();
}

interface Q {
    void q();
}       

interface R {
    void r();
}

class PQR implements P, Q, R {
    @Override
    public void p() {
        System.out.println("P");
    }

    @Override
    public void q() {
        System.out.println("Q");
    }

    @Override
    public void r() {
        System.out.println("R");
    }
}

class A {
    public void a(P pRef) {
        pRef.p();
    }
}

class B {
    public void b(Q qRef) {
        qRef.q();
    }
}

class C {
    public void c(R rRef) {
        rRef.r();
    }
}

public class InterfaceDemo {
    public static void main(String[] args) {
        P p = new PQR();
        A ainvoker = new A();
        ainvoker.a(p);

        Q q = new PQR();
        B binvoker = new B();
        binvoker.b(q);

        R r = new PQR();
        C cinvoker = new C();
        cinvoker.c(r);
    }
}


0 commentaires