[JAVA] [Details] Lassen Sie uns abstrakte Klassen und Schnittstellen beherrschen! !!

Einführung

Verstehst du den Unterschied zwischen abstrakten Klassen und Schnittstellen? Verstehst und beherrschst du es auch?

Auch wenn Sie viele Senioren fragen oder online nachschlagen ... ** Schnittstelle, wenn Sie den Typ als Klassenspezifikation definieren möchten ** ** Abstrakte Klasse, wenn Sie eine Vererbungsbeziehung haben und die Verarbeitung wiederverwenden möchten ** Wird zurückgegeben. Ich weiß es bereits, ich glaube ich verstehe es, aber ich kann es nicht beherrschen.

Wie verstehst und beherrschst du es? ** Sie sollten die Essenz verstehen (warum hat es solche Spezifikationen?), Nicht den Unterschied auf der Oberfläche ** Dieser Artikel ist eine Zusammenstellung meiner Forschung.

Was ist eine abstrakte Klasse?

Zusammenfassend lässt sich sagen, dass ** abstrakte Klassen vererbt werden und verwendet werden, wenn Sie die Verarbeitung wiederverwenden möchten **.

Konzept

Die "Vererbungs" -Beziehung zwischen einer abstrakten Klasse und einer konkreten Klasse wird als ** IS A-Beziehung ** bezeichnet. ** Hund ist ein Tier ** = ** Hund ist ein Tier ** Es ist eine Eltern-Kind-Beziehung. Schreiben wir also die gemeinsamen Handlungen (Prozesse), die Hunde und Menschen in der Tierklasse (abstrakte Klasse) haben! Wird gesagt, dass. Einmal zusammengefasst, ** schreibe in einer abstrakten Klasse, was jedes Kind tun kann, und schreibe konkrete Dinge, die nur dieses Kind in einer konkreten Klasse tun kann **

Beispielcode

Schreiben wir einen Beispielcode anhand des obigen Beispiels. Wenn Sie abstrakt über abstrakte Klassen nachdenken, haben Tiere Namen. Und nachts kann man schlafen, essen und reden.

Da alle Tiere das gleiche Schlafverhalten haben, werden sie in einer gemeinsamen abstrakten Klasse implementiert. (Sag nicht, dass du anders schläfst) Sie können essen und sprechen, aber die Besonderheiten variieren von Tier zu Tier. Definieren Sie es daher als abstrakte Methode.

Animal.java


public abstract class Animal {
	String name;
	
	public Animal(String name){
		this.name = name;
	}
	
	public void sleep(){
		System.out.println("schlafen");
	}
	public abstract void speak();
	
	public abstract void eat();
}

Da die Art und Weise, wie Hunde sprechen und essen, unterschiedlich ist, werden wir dies konkret in der konkreten Klasse umsetzen.

Dog.java


public class Dog extends Animal{
	
	public Dog(String name){
		super(name);
	}

	@Override
	public void speak() {
		System.out.println("mein Name ist"+name+"Dawan! !!");
	}

	@Override
	public void eat() {
		System.out.println("Gab Gab Gab");
	}
}

Ebenso werden Sprechen und Essen in der konkreten Klasse konkret umgesetzt.

Human.java


public class Human extends Animal{

	public Human(String name) {
		super(name);
	}

	@Override
	public void speak() {
		System.out.println("Schön dich kennenzulernen, mein Name ist"+name+"ist.");		
	}

	@Override
	public void eat() {
		System.out.println("Mogumogu");		
	}
}

Klasse zum Aufrufen der erstellten Klasse

Main.java


public class Main {
	public static void main(String[] arg){
		Human tarou = new Human("Taro");
		Dog pochi = new Dog("Pochi");
		
		System.out.println("****Taros Verarbeitung****");
		tarou.sleep();
		tarou.eat();
		tarou.speak();
		
		System.out.println("****Pochi Verarbeitung****");
		pochi.sleep();
		pochi.eat();
		pochi.speak();
	}
}

/*Ausgabeergebnis
****Taros Verarbeitung****
schlafen
Mogumogu
Schön dich kennenzulernen, mein Name ist Taro.
****Pochi Verarbeitung****
schlafen
Gab Gab Gab
Ich heiße Pochi One! !!
*/

Was ist eine Schnittstelle?

Zusammenfassend ist ** eine Schnittstelle eine Typdefinition als Klassenspezifikation **.

Konzept

Zuallererst bedeutet das Wort der Schnittstelle "Standards und Spezifikationen für den Anschluss von Computern und Peripheriegeräten oder Betriebsmethoden und -konzepte für Benutzer zur Verwendung von Computern usw. In der Hardware Standards für Anschlüsse, die Geräte miteinander verbinden. Bezieht sich auf. " Einfacher ausgedrückt ist es ** ein Fenster, das etwas verbindet, das von außen gesehen werden kann **.

Und die Beziehung zwischen der Schnittstelle und der "Implementierung" der Implementierungsklasse wird als ** CAN DO-Beziehung ** bezeichnet. ** Registrierkasse KANN Kreditkarte abrechnen ** = ** Die Registrierkasse kann für die Kreditkartenabrechnung verwendet werden. Es ist eine Beziehung wie **. Darüber hinaus kann die Registrierkasse auch für die Kassenbuchhaltung verwendet werden. In der Schnittstelle wird daher definiert, dass eine Registrierkasse erstellt werden kann und nur die Buchhaltung definiert ist. Unter einem anderen Gesichtspunkt ist es wie ** zu definieren, dass Sie sich von außen registrieren können, ohne sich dessen bewusst zu sein. Dann * sollte der Angestellte, der die Registrierkasse benutzt, in der Lage sein, nur die Buchhaltung durchzuführen, ohne darüber nachzudenken, um welche Art von Buchhaltung es sich handelt **.

Beispielcode

Schreiben wir einen Beispielcode anhand des obigen Beispiels. In der Registrierkassenschnittstelle wird nur definiert, was getan werden kann (= Buchhaltung), und die Sachbearbeiterklasse, die die Registrierkasse verwendet, führt nur die Buchhaltung aus. Die Kredit- und Bargeldbuchhaltung implementiert die in der Schnittstelle definierte Buchhaltung.

Definieren Sie eine Abrechnungsmethode in der Registrierkassenschnittstelle.

Cashier.java


public interface Cashier {
	public void bill();
}

Implementieren Sie die Schnittstelle und die Details der Kreditbuchhaltung.

CreditCard.java


public class CreditCard implements Cashier{
	@Override
	public void bill() {
		System.out.println("Wir bezahlen mit Kreditkarte.");
	}
}

Implementieren Sie die Schnittstelle und implementieren Sie die Details der Bargeldabrechnung.

Cash.java


public class Cash implements Cashier{
	@Override
	public void bill() {
		System.out.println("Wir zahlen in bar.");	
	}
}

Und der Angestellte führt die Kasse der Registrierkasse durch. Da ich derzeit die Kassierer-Rechnung anrufe, frage ich mich, ob dies eine Bargeld- oder eine Kreditbuchhaltung ist Sie können es verwenden, ohne sich dessen bewusst zu sein.

Staff.java


public class Staff {
	public static void main(String[] arg) {
		Cashier cash = new Cash();
		Cashier credit = new CreditCard();
		
		System.out.println("***Bargeldunterstützung***");
		cash.bill();
		
		System.out.println("***Kreditunterstützung***");
		credit.bill();
	}
}

Organisieren Sie einmal über abstrakte Klassen und Schnittstellen

Bisher habe ich die abstrakten Klassen und Schnittstellen skizziert. Wir werden es von nun an genauer betrachten, aber lassen Sie es uns zuerst hier organisieren. Was ist eine abstrakte Klasse? Die "Vererbungs" -Beziehung zwischen der abstrakten Klasse und der konkreten Klasse ist die ** IS A-Beziehung **, die zusammenfasst, was Kinder in der übergeordneten Klasse auf abstrakte Weise tun können.

Was ist eine Schnittstelle? Die "Implementierungs" -Beziehung zwischen der Schnittstelle und der Implementierungsklasse ist ** CAN DO-Beziehung **, die nur definiert, was die Schnittstelle tun kann, und die Einzelheiten der Implementierungsklasse überlässt. Der Benutzer muss sich also nicht um die darin implementierten Details kümmern.

Persönliche Gedanken

Meiner Meinung nach werden abstrakte Klassen und Schnittstellen grundsätzlich zusammen verwendet (oder werden verwendet). Ich denke, ich benutze eine Schnittstelle, definiere Funktionen, die von außen verwendet werden können ** und verwende abstrakte Klassen, um die gemeinsame Verarbeitung innerhalb von ** zu organisieren. Dies wird später unter "Zugriffsqualifizierer" ausführlich erläutert.

Unterschied zwischen abstrakter Klasse und Schnittstelle

Um die Essenz von hier aus zu verstehen ** Warum ist es eine solche Spezifikation? Wir werden aus der Perspektive von ** tiefer graben. Lassen Sie uns zunächst die Unterschiede zwischen abstrakten Klassen und Schnittstellen zusammenfassen.

f Abstrakte Klasse Schnittstelle
Zugriffsmodifikator public,protected nur öffentlich
Variablendefinition Sie können Instanzvariablen, lokale Variablen und Klassenvariablen definieren. Es können nur öffentliche statische Endkonstanten (Klassenvariablen) gehalten werden.
Es kann nicht vom geerbten Ziel überschrieben werden.
Erbe Mehrfachvererbung nicht möglich Mehrfachvererbung möglich
Methodendefinition Wenden Sie eine bestimmte Verarbeitung an Es können nur Methodentypen definiert werden.
Ab Java8 wird die Verarbeitung auch mit der Standardmethode ausgeführt.

Warum unterscheiden sich die Zugriffsmodifikatoren, die angegeben werden können?

Die Schnittstelle ist nur öffentlich. Abstrakte Klassen können nur öffentlich und geschützt definieren. Sie können öffentlich definierte Methoden von überall aus aufrufen! In dem Sinne, dass In protected definierte Methoden können nur innerhalb dieses Pakets aufgerufen werden! Es bedeutet das.

Dies bedeutet, dass öffentliche Methoden zum Aufrufen von außen dienen → für diejenigen, die sie außerhalb verwenden → ** Die Schnittstelle definiert Methoden für diejenigen, die sie verwenden **.

Daher können geschützte Methoden nur innerhalb eines Pakets verwendet werden → für diejenigen, die es innerhalb verwenden → ** abstrakte Klassen sind für diejenigen, die es innerhalb verwenden **.

Zusammenfassung

Da die Schnittstelle für ** externe Benutzer ** vorgesehen ist, können nur öffentliche Methoden definiert werden. Da die abstrakte Klasse für ** Personen ist, die sie in ** verwenden, kann sogar geschützt definiert werden.

Eine Mehrfachvererbung von abstrakten Klassen ist nicht möglich, aber Schnittstellen sind möglich. Warum?

Mehrfachvererbung ist ** Vererbung mehrerer übergeordneter Klassen **. Abstrakte Klassen erlauben keine Mehrfachvererbung, sondern Schnittstellen. Das rautenförmige Vererbungsproblem wird häufig als Beispiel für Mehrfachvererbung angeführt. 多重継承.png

In Anbetracht der Probleme, die durch Mehrfachvererbung verursacht werden (es scheint Mix-In zu heißen), kann Folgendes erwähnt werden.

Weil abstrakte Klassen instanziiert werden können (tatsächlich das Gefühl, die Methoden zu entwickeln, die abstrakte Klassen haben !?) Dieses Problem tritt auf. Daher ist es in den Spezifikationen nicht erlaubt. Was ist dann mit der Schnittstelle? Es gibt eine Regel, um diese beiden Probleme zu lösen. -Methodenaufruf Die der Klasse am nächsten liegende Methode wird aufgerufen -Wenn die Priorität des Methodenaufrufs nicht bestimmt werden kann oder gleich wird, wird eine Überschreibung als Kompilierungsfehler angezeigt. · Die Schnittstelle kann nicht instanziiert werden (Die in die Schnittstelle geschriebene Methode ist nur mit der tatsächlichen Situation verknüpft und wird daher nicht instanziiert.)

Zusammenfassung

Die abstrakte Klasse verfügt über eine Spezifikation, die nicht mehrmals vererbt werden kann, da beim Instanziieren Probleme wie die Namensauflösung auftreten. Die Schnittstelle kann nicht instanziiert werden und ist in der Instanz nur als "Schnittstelle" ** enthalten, sodass eine Mehrfachvererbung möglich ist. Hier War sehr hilfreich.

Warum hat die Schnittstelle keine Instanzvariablen?

Dies liegt daran, dass die Schnittstelle nicht wie bei der Mehrfachvererbung erwähnt instanziiert werden kann. Es verhindert lediglich, dass Sie Instanzvariablen haben. Um es anders herum auszudrücken: Eine Instanzvariable verursacht Probleme.

Zusammenfassung

Da Probleme aufgrund der Mehrfachvererbung auftreten, sind die Spezifikationen so, dass nur ** öffentliche statische Endkonstanten ** gehalten werden können.

Warum wurde die Standardmethode von Java8 eingeführt?

Lassen Sie uns zunächst über die Standardmethode sprechen. Die Standardmethode ist ** eine Methode, die bestimmte Verarbeitungsinhalte implementiert, die in der Schnittstelle definiert werden können **. Dadurch entfällt die Notwendigkeit, die Verarbeitung der Methode innerhalb der zu implementierenden Klasse zu überschreiben und zu beschreiben.

Ich denke, das wirft Fragen auf. Der Unterschied zwischen einer abstrakten Klasse und einer Schnittstelle ist verschwunden. .. .. Es scheint, dass der Hintergrund, der an erster Stelle erstellt wurde, bei meiner Untersuchung völlig anders ist.

In Java8 können Sie die Stream-API verwenden.

In der List-Oberfläche gab es tatsächlich die Standardmethode.

    default void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        final ListIterator<E> li = this.listIterator();
        while (li.hasNext()) {
            li.set(operator.apply(li.next()));
        }
    }

Zusammenfassung

Die Standardmethode der Schnittstelle ist eine Methode, die aus Gründen der Kompatibilität zwischen Java7 und Java8 erstellt wurde. Also fand ich heraus, dass es sich völlig von der abstrakten Klasse unterscheidet, weil es nicht zum Organisieren der gemeinsamen Verarbeitung dient.

Zusammenfassung im gesamten

Es stellt sich heraus, dass abstrakte Klassen und Schnittstellen in ihren Funktionen ähnlich sein können, die erstellten Hintergründe und Spezifikationen jedoch sehr unterschiedlich sind. Die abstrakte Klasse ist in ** für diejenigen, die sie verwenden, um gemeinsame Prozesse zu organisieren **, Die Benutzeroberfläche war in ** für externe Benutzer ** eine völlig andere Sache und definierte, was Sie tun können, ohne Details anzuzeigen.

Nebenbei bemerkt, als ich den Artikel tatsächlich schrieb, vertiefte ich mein Verständnis und stellte fest, dass es viele Fälle gab, in denen ich tatsächlich falsch verwendet wurde. Wenn Sie Fragen oder Bedenken haben, kommentieren Sie bitte.

Recommended Posts

[Details] Lassen Sie uns abstrakte Klassen und Schnittstellen beherrschen! !!
Verstehe den Unterschied zwischen abstrakten Klassen und Schnittstellen!
Java abstrakte Methoden und Klassen
JAVA lernen Geschichte abstrakte Klassen und Methoden
Ein Hinweis zu den Unterschieden zwischen Schnittstellen und abstrakten Klassen in Java
Effektive Java 3rd Edition Kapitel 4 Klassen und Schnittstellen
Schnittstelle und Zusammenfassung
[Ruby] Klassen und Instanzen
Über Klassen und Instanzen
Ruby-Klassen und -Instanzen
Liste und fröhliche Klassen
Java (Klasse und Instanz)