Comprenez-vous la différence entre les classes abstraites et les interfaces? Aussi, le comprenez-vous et le maîtrisez-vous?
Même si vous demandez à beaucoup de personnes âgées ou si vous recherchez en ligne ... ** Interface si vous souhaitez définir le type comme spécification de classe ** ** Classe abstraite si vous avez une relation d'héritage et souhaitez réutiliser le traitement ** Sera retourné. Je le sais déjà, je pense le comprendre, mais je ne peux pas le maîtriser.
Alors, comment le comprenez-vous et le maîtrisez-vous? ** Vous devez comprendre l'essence (pourquoi il a de telles spécifications?), Pas la différence en surface ** Cet article est une compilation de mes recherches.
En conclusion, les ** classes abstraites sont héritées et sont utilisées lorsque vous souhaitez réutiliser le traitement **.
On dit que la relation «d'héritage» entre une classe abstraite et une classe concrète est une relation ** IS A **. ** Le chien EST un animal ** = ** Le chien est un animal ** Il s'agit d'une relation parent-enfant. Alors écrivons les actions communes (processus) que les chiens et les humains ont dans la classe animale (classe abstraite)! Est dit être. Une fois résumé, ** écrivez dans une classe abstraite ce que chaque enfant peut faire et écrivez des choses concrètes que seul cet enfant peut faire dans une classe concrète **
Écrivons un exemple de code en utilisant l'exemple ci-dessus. Maintenant, si vous pensez abstraitement aux classes abstraites, les animaux ont des noms. Et la nuit, vous pouvez dormir, manger et parler.
Puisque le comportement de sommeil est le même pour tous les animaux, il est implémenté dans une classe abstraite commune. (Ne dis pas que tu dors différemment) Vous pouvez manger et parler, mais les spécificités varient d'un animal à l'autre, alors définissez-la comme une méthode abstraite.
Animal.java
public abstract class Animal {
String name;
public Animal(String name){
this.name = name;
}
public void sleep(){
System.out.println("dormir");
}
public abstract void speak();
public abstract void eat();
}
Puisque la façon dont les chiens parlent et mangent est différente, nous allons l'implémenter concrètement dans la classe concrète.
Dog.java
public class Dog extends Animal{
public Dog(String name){
super(name);
}
@Override
public void speak() {
System.out.println("mon nom est"+name+"Dawan! !!");
}
@Override
public void eat() {
System.out.println("Gab Gab Gab");
}
}
De même, parler et manger sont concrètement implémentés dans la classe concrète.
Human.java
public class Human extends Animal{
public Human(String name) {
super(name);
}
@Override
public void speak() {
System.out.println("Ravi de vous rencontrer, je m'appelle"+name+"est.");
}
@Override
public void eat() {
System.out.println("Mogumogu");
}
}
Classe pour appeler la classe créée
Main.java
public class Main {
public static void main(String[] arg){
Human tarou = new Human("Taro");
Dog pochi = new Dog("Pochi");
System.out.println("****Traitement de Taro****");
tarou.sleep();
tarou.eat();
tarou.speak();
System.out.println("****Traitement Pochi****");
pochi.sleep();
pochi.eat();
pochi.speak();
}
}
/*Résultat de sortie
****Traitement de Taro****
dormir
Mogumogu
Ravi de vous rencontrer, je m'appelle Taro.
****Traitement Pochi****
dormir
Gab Gab Gab
Je m'appelle Pochi One! !!
*/
En conclusion, ** une interface est une définition de type en tant que spécification de classe **.
Tout d'abord, le sens du mot interface est «normes et spécifications pour la connexion d'ordinateurs et de périphériques, ou méthodes et concepts de fonctionnement permettant aux utilisateurs d'utiliser des ordinateurs, etc. En matériel, normes pour les connecteurs qui connectent des périphériques entre eux. Fait référence à. " Pour le dire plus simplement, c'est ** une fenêtre qui relie quelque chose qui peut être vu de l'extérieur **.
Et la relation entre l'interface et «l'implémentation» de la classe d'implémentation est dite être la ** relation CAN DO **. ** Caisse enregistreuse CAN facture Carte de crédit ** = ** La caisse enregistreuse peut être utilisée pour la comptabilité par carte de crédit. C'est une relation comme **. De plus, la caisse enregistreuse peut également être utilisée pour la comptabilité de caisse. Par conséquent, ce qui est défini dans l'interface, c'est que la caisse enregistreuse peut être effectuée et que seule la comptabilité est définie. D'un autre point de vue, c'est comme ** définir que vous pouvez vous inscrire de l'extérieur sans en être conscient. Ensuite, * le commis qui utilise la caisse enregistreuse devrait être en mesure de faire la comptabilité sans penser à quel type de comptabilité il s'agit **.
Écrivons un exemple de code en utilisant l'exemple ci-dessus. Seule ce qui peut être fait (= comptabilité) est défini dans l'interface de la caisse enregistreuse, et la classe de commis qui utilise la caisse enregistreuse exécute uniquement la comptabilité. La comptabilité crédit et caisse met en œuvre la comptabilité définie dans l'interface.
Définissez une méthode comptable dans l'interface de la caisse enregistreuse.
Cashier.java
public interface Cashier {
public void bill();
}
Implémentez l'interface et implémentez les détails de la comptabilité de crédit.
CreditCard.java
public class CreditCard implements Cashier{
@Override
public void bill() {
System.out.println("Nous paierons avec une carte de crédit.");
}
}
Implémentez l'interface et implémentez les détails de la comptabilité de caisse.
Cash.java
public class Cash implements Cashier{
@Override
public void bill() {
System.out.println("Nous paierons en espèces.");
}
}
Et le greffier vérifiera la caisse enregistreuse. Puisque j'appelle la facture du caissier en ce moment, je me demande s'il s'agit de comptabilité de caisse ou de comptabilité de crédit Vous pouvez l'utiliser sans en avoir conscience.
Staff.java
public class Staff {
public static void main(String[] arg) {
Cashier cash = new Cash();
Cashier credit = new CreditCard();
System.out.println("***Soutien en espèces***");
cash.bill();
System.out.println("***Aide au crédit***");
credit.bill();
}
}
Jusqu'à présent, j'ai décrit les classes abstraites et les interfaces. Nous allons l'examiner plus en profondeur à partir de maintenant, mais organisons-le d'abord ici. Qu'est-ce qu'une classe abstraite? La relation «d'héritage» entre la classe abstraite et la classe concrète est la ** relation IS A **, qui résume ce que les enfants peuvent faire dans la classe parente de manière abstraite.
Qu'est-ce qu'une interface? La relation «d'implémentation» entre l'interface et la classe d'implémentation est la ** relation CAN DO **, qui définit uniquement ce que l'interface peut faire et laisse les détails à la classe d'implémentation. Ainsi, l'utilisateur n'a pas à se soucier des détails mis en œuvre à l'intérieur.
À mon avis, les classes abstraites et les interfaces sont essentiellement utilisées (ou seront utilisées) ensemble. Je pense utiliser une interface, définir des fonctions qui peuvent être utilisées ** de l'extérieur et utiliser des classes abstraites pour organiser le traitement commun à l'intérieur **. Cela sera expliqué en détail plus loin dans "Qualificatifs d'accès".
Pour comprendre l'essence d'ici ** Pourquoi est-ce une telle spécification? Nous allons creuser plus profondément du point de vue de **. Tout d'abord, résumons les différences entre les classes abstraites et les interfaces.
f | Classe abstraite | interface |
---|---|---|
Modificateur d'accès | public,protected | public uniquement |
Définition variable | Vous pouvez définir des variables d'instance, des variables locales et des variables de classe. | Seules les constantes finales statiques publiques (variables de classe) peuvent être conservées. Il ne peut pas être écrasé par la destination héritée. |
Héritage | L'héritage multiple n'est pas possible | Héritage multiple possible |
Définition de la méthode | Appliquer un traitement spécifique | Seuls les types de méthode peuvent être définis. À partir de java8, le traitement est également effectué à l'aide de la méthode par défaut. |
L'interface est publique uniquement. Les classes abstraites ne peuvent définir que public et protected. Vous pouvez appeler des méthodes définies publiquement de n'importe où! Dans le sens où Les méthodes définies dans protected ne peuvent être appelées qu'à partir de ce package! Cela signifie que.
Cela signifie que les méthodes publiques sont destinées à appeler de l'extérieur → pour ceux qui l'utilisent à l'extérieur → ** l'interface définit des méthodes pour ceux qui l'utilisent **.
Les méthodes protégées ne peuvent donc être utilisées qu'à l'intérieur d'un paquet → pour ceux qui l'utilisent à l'intérieur → ** les classes abstraites sont pour ceux qui l'utilisent à l'intérieur **.
Puisque l'interface est destinée aux ** utilisateurs extérieurs **, seules les méthodes publiques peuvent être définies. Puisque la classe abstraite est pour ** les personnes qui l'utilisent dans **, même protégé peut être défini.
L'héritage multiple ** hérite de plusieurs classes parentes **. Les classes abstraites ne permettent pas l'héritage multiple par conception, mais autorisent les interfaces. Le problème de l'héritage en forme de losange est souvent cité comme un exemple d'héritage multiple.
Compte tenu des problèmes causés par l'héritage multiple (il semble s'appeler Mix-In), on peut mentionner ce qui suit. -Problème de résolution de nom en raison de noms de méthodes en double Ou le nom de méthode de ClassB et ClassC doit avoir l'un ou l'autre parce qu'il est le même dans ClassD? Ou devrait-il être mis en œuvre? ・ Problèmes causés par l'héritage de classes plusieurs fois Comme ClassB et ClassC héritent de ClassA, ClassD hérite de ClassA deux fois.
Parce que la classe abstraite peut être instanciée (réelle, le sentiment de créer la méthode que la classe abstraite a!?) Ce problème se produit. Ce n'est donc pas autorisé dans les spécifications. Alors qu'en est-il de l'interface? Il existe une règle pour résoudre ces deux problèmes. -Appel de méthode La méthode la plus proche de la classe est appelée -Si la priorité d'appel de méthode ne peut pas être déterminée ou devient la même, un remplacement est demandé comme une erreur de compilation. · L'interface ne peut pas être instanciée (La méthode écrite dans l'interface est uniquement liée à la situation réelle, elle n'est donc pas instanciée.)
La classe abstraite a une spécification qui ne peut pas être héritée plusieurs fois car des problèmes tels que la résolution de nom se produisent lors de son instanciation. L'interface ne peut pas être instanciée et elle est uniquement contenue dans l'instance en tant qu '"interface" **, donc l'héritage multiple est possible. Ici Était très utile.
Cela est dû au fait que l'interface ne peut pas être instanciée comme mentionné lors de l'héritage multiple. Cela vous empêche simplement d'avoir des variables d'instance. Pour le dire autrement, avoir une variable d'instance pose des problèmes.
Étant donné que des problèmes surviennent en raison de l'héritage multiple, les spécifications sont telles que seules les ** constantes finales statiques publiques ** peuvent être conservées.
Tout d'abord, parlons de la méthode par défaut. La méthode par défaut est ** une méthode qui implémente des contenus de traitement spécifiques qui peuvent être définis dans l'interface **. Cela élimine le besoin de remplacer et de décrire le traitement de la méthode dans la classe à implémenter.
Je pense que cela soulève des questions. La différence entre une classe abstraite et une interface a disparu. .. .. Il semble que l'arrière-plan créé en premier lieu soit complètement différent lorsque j'enquête.
Depuis java8, vous pouvez utiliser l'API Stream.
En regardant l'interface List, la méthode par défaut existait réellement.
default void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final ListIterator<E> li = this.listIterator();
while (li.hasNext()) {
li.set(operator.apply(li.next()));
}
}
La méthode par défaut de l'interface est une méthode créée pour la compatibilité entre java7 et java8. J'ai donc trouvé qu'elle est complètement différente de la classe abstraite car elle n'est pas destinée à regrouper des processus communs.
Il s'avère que les classes abstraites et les interfaces peuvent être similaires dans ce qu'elles peuvent faire, mais les arrière-plans et les spécifications créés sont assez différents. La classe abstraite est en ** pour ceux qui l'utilisent pour organiser des processus communs **, L'interface était une chose complètement différente dans ** pour les utilisateurs externes **, définissant ce que vous pouvez faire sans afficher les détails.
En passant, en écrivant l'article, j'ai approfondi ma compréhension et réalisé qu'il y avait de nombreux cas où j'étais en fait mal utilisé. Si vous avez des questions ou des préoccupations, veuillez commenter.
Recommended Posts