[JAVA] Beispiel für die Verwendung einer abstrakten Klasse

Einführung

Ich kenne die Bedeutung und Definition von abstrakten Klassen, aber wann ich sie verwenden soll und welche guten Dinge gibt es? Vergleichen wir das implementierte Programm mit der abstrakten Klasse und das ohne sie implementierte Programm, um dieselbe Anforderung zu bestätigen.

JAVA-Programm

Angenommen, es gibt zwei Arten von Druckern: Tintenstrahldrucker und Laser. Erstellen Sie ein Programm, das mehrere davon verwaltet und eine Liste der verwalteten Druckerinformationen anzeigt.

Programme, die keine abstrakten Klassen verwenden

https://paiza.io/projects/Iwnh9NgDAaxPSZC36uZqsw

Klassenstruktur: image.png

Es gibt nur InkjetPrinter- und LaserPrinter-Klassen. Jedes hat einen Modellnamen (mModelName) und die verbleibende Anzahl von Blättern (mPaper) als Mitgliedsvariablen. Es hat auch eine getPrinterInfo () -Funktion, die Druckerinformationen zurückgibt.

Der Unterschied besteht darin, dass der InkjetPrinter die verbleibende Tintenmenge (mRemainingInk) und der LaserPrinter die verbleibende Tonermenge (mRemainingToner) enthält.

Programm mit abstrakter Klasse

https://paiza.io/projects/Xs-iNK2-SYDnlYIp1oWF3w

Klassenstruktur: image.png

Wir haben eine abstrakte Klasse AbstractPrinter erstellt, indem wir die allgemeinen Teile der InkjetPrinter-Klasse und der LaserPrinter-Klasse verallgemeinert haben (Modellname der Mitgliedsvariablen, verbleibende Papiermenge und Funktion, die Druckerinformationen zurückgibt). Die Klassen InkjetPrinter und LaserPrinter erben von AbstractPrinter.

Ausführungsergebnis

Beide geben das gleiche Ergebnis aus.

Ausgabeergebnis


[Inkjet]Epson P1 Anzahl der bedruckbaren Blätter: 10
[Inkjet]Canon C1 druckbare Nummer: 20
[Laser-]Xerox X1 Anzahl der bedruckbaren Blätter: 100
[Laser-]Ricoh R1 Anzahl der bedruckbaren Blätter: 50
[Laser-]Richo R2 Anzahl der bedruckbaren Blätter: 200

Was ist der Unterschied

Ich kann Ihnen zwei Punkte geben.

Zunächst die Klassenstruktur. Eine unabhängige Klasse und eine abstrahierte Klasse. Das Konzept der abstrakten Klassen wird in Büchern und Sites, die die Objektorientierung erklären, ausführlich erläutert, daher werde ich es hier weglassen.

Der andere Punkt ist, wie man es von der Managementseite aus verwendet. Schauen wir uns das genauer an.

Wenn Sie keine abstrakten Klassen verwenden

Main, wenn keine abstrakten Klassen verwendet werden()


    public static void main(String[] args) throws Exception {

        //Registrieren Sie den zu verwaltenden Tintenstrahldrucker.
        InkjetPrinter[] inkjets = {
            new InkjetPrinter("Epson P1", 10),
            new InkjetPrinter("Canon C1", 20),
        };
        
        //Registrieren Sie den zu verwaltenden Laserdrucker.
        LaserPrinter[] lasers = {
            new LaserPrinter("Xerox X1", 100),
            new LaserPrinter("Richo R1", 50),
            new LaserPrinter("Richo R2", 200),
        };
        
        //Listen Sie die verwalteten Drucker auf.
        //Zunächst der Tintenstrahldrucker.
        for(int i = 0; i < inkjets.length; i++ ){
            System.out.println(inkjets[i].getPrinterInfo());
        }
        
        //Als nächstes ein Laserdrucker.
        for(int i = 0; i < lasers.length; i++ ){
            System.out.println(lasers[i].getPrinterInfo());
        }
    }

Es gibt keine Beziehung zwischen der InkjetPrinter-Klasse und der LaserPrinter-Klasse, jeder ist ein unabhängiger "Typ".

** Objekte der InkjetPrinter-Klasse können nur in Variablen vom Typ InkjetPrinter gespeichert werden, und Objekte der LaserPrinter-Klasse können nur in Variablen vom Typ LaserPrinter gespeichert werden. ** ** **

Daher wird eine Variable des Typs für jeden Druckertyp (in diesem Fall ein Array) vorbereitet, das Druckerobjekt wird gespeichert und die Druckerliste wird durch Schleifen ausgegeben.

Bei Verwendung einer abstrakten Klasse

Haupt bei Verwendung von abstrakten Klassen()


    public static void main(String[] args) throws Exception {

        //Registrieren Sie den zu verwaltenden Drucker.
        AbstractPrinter[] printers = {
            new InkjetPrinter("Epson P1", 10),
            new InkjetPrinter("Canon C1", 20),
            new LaserPrinter("Xerox X1", 100),
            new LaserPrinter("Richo R1", 50),
            new LaserPrinter("Richo R2", 200),
        };
        
        //Listen Sie die verwalteten Drucker auf.
        for(int i = 0; i < printers.length; i++ ){
            System.out.println(printers[i].getPrinterInfo());
        }
    }

Die Klassen InkjetPrinter und LaserPrinter leiten sich von der Klasse "AbstractPrinter" ab, die eine Abstraktion des "Druckers" ist. Die AbstractPrinter-Klasse ist eine allgemeine übergeordnete Klasse.

** Variablen können Objekte dieses Typs und von diesem Typ abgeleitete Objekte speichern. ** ** **

Daher kann die Variable vom Typ AbstractPrinter das InkjetPrinter-Klassenobjekt und das LaserPrinter-Klassenobjekt speichern, und die in dieser Variablen enthaltenen Objekte können als AbstractPrinter-Klasse behandelt werden.

Infolgedessen sind die Variablen, die den Drucker verwalten, eins geworden, und die Verarbeitung für die Anzeige ist auch eins geworden.

Was für gute Dinge gibt es

Durch die Einführung der abstrakten Klasse sind die verwalteten Variablen und die Anzeigeverarbeitung intelligenter geworden. Dies allein ist gut, aber es gibt einige sehr gute Dinge wie Verbesserungen, die Sie "resistent gegen Änderungen" machen.

Angenommen, Sie müssen Änderungen vornehmen, um Ihrem Druckertyp einen Punktdrucker hinzuzufügen.

Wenn Sie keine abstrakten Klassen verwenden, lautet die Quelle: Dies ist die Zeile, die durch den Prozess hinzugefügt wurde, der "★ Hinzufügen ★" kommentierte.

Wenn Sie keine abstrakten Klassen verwenden

Klassenstruktur: image.png

Main, wenn keine abstrakten Klassen verwendet werden()


    public static void main(String[] args) throws Exception {

        //Registrieren Sie den zu verwaltenden Tintenstrahldrucker.
        InkjetPrinter[] inkjets = {
            new InkjetPrinter("Epson P1", 10),
            new InkjetPrinter("Canon C1", 20),
        };
        
        //Registrieren Sie den zu verwaltenden Laserdrucker.
        LaserPrinter[] lasers = {
            new LaserPrinter("Xerox X1", 100),
            new LaserPrinter("Richo R1", 50),
            new LaserPrinter("Richo R2", 200),
        };
        
        //★ Ergänzung ★
        //Registrieren Sie den zu verwaltenden Punktdrucker.
        DotimpactPrinter[] dotimpacts = {
            new DotimpactPrinter("NEC N1", 100),
            new DotimpactPrinter("Oki O1", 50),
        };

        //Listen Sie die verwalteten Drucker auf.
        //Zunächst der Tintenstrahldrucker.
        for(int i = 0; i < inkjets.length; i++ ){
            System.out.println(inkjets[i].getPrinterInfo());
        }
        
        //Als nächstes ein Laserdrucker.
        for(int i = 0; i < lasers.length; i++ ){
            System.out.println(lasers[i].getPrinterInfo());
        }

        //★ Ergänzung ★
        //Als nächstes kommt der Punktdrucker.
        for(int i = 0; i < dotimpacts.length; i++ ){
            System.out.println(dotimpacts[i].getPrinterInfo());
        }
    }

Bei Verwendung einer abstrakten Klasse

Klassenstruktur: image.png

Haupt bei Verwendung von abstrakten Klassen()


    public static void main(String[] args) throws Exception {

        //Registrieren Sie den zu verwaltenden Drucker.
        AbstractPrinter[] printers = {
            new InkjetPrinter("Epson P1", 10),
            new InkjetPrinter("Canon C1", 20),
            new LaserPrinter("Xerox X1", 100),
            new LaserPrinter("Richo R1", 50),
            new LaserPrinter("Richo R2", 200),
            new DotimpactPrinter("NEC N1", 100), //★ Ergänzung ★
            new DotimpactPrinter("Oki O1", 50),  //★ Ergänzung ★
        };
        
        //Listen Sie die verwalteten Drucker auf.
        for(int i = 0; i < printers.length; i++ ){
            System.out.println(printers[i].getPrinterInfo());
        }
    }

Für diejenigen, die keine abstrakten Klassen verwenden, haben wir Variablen hinzugefügt, die Punktauswirkungsdrucker verwalten und die Schleifenverarbeitung, die sie anzeigt. Eine ähnliche Verarbeitung hat zugenommen. Es ist überflüssig.

Auf der anderen Seite haben diejenigen, die die abstrakte Klasse verwendet haben, das Druckerobjekt mit Punktauswirkung nur zur Druckervariablen hinzugefügt, die den Drucker verwaltet, und es gab keine Änderung im Anzeigeprozess. Der Umfang der Programmänderungen ist gering.

Zusammenfassung

Tatsächlich ist dieser Vorteil nicht der Effekt der abstrakten Klasse, sondern der Vorteil der Verallgemeinerung / Vererbung der Klasse. Die Verwendung einer abstrakten Klasse bedeutet Abstraktion + Generalisierung / Vererbung, sodass Sie von Generalisierung / Vererbung profitieren können.

Recommended Posts

Beispiel für die Verwendung einer abstrakten Klasse
Beispiel für die Verwendung von vue.config.js
[Kotlin] Ein Beispiel für die Verarbeitung mit Enum
Java (abstrakte Klasse)
Richtige Verwendung der Schnittstelle und der abstrakten Klasse
Beispiel für die Verwendung von ArAutoValueConverter (Feldtypkonvertierung)
[Java] Abstrakte Klasse
Ein Beispiel, bei dem die Verwendung von Addition schneller ist als die Verwendung von StringBuilder (Java)
Verwendung der Datumsklasse
Anwendungsbeispiel für die innere Klasse
Zusammenfassung der Verwendung von FragmentArgs
Zusammenfassung der Verwendung von DBFlow
Über die abstrakte Klasse von Java
Schnittstelle / Abstrakte Klasse / Überschreiben
Ausgabe des Tages mit der Ruby's Date-Klasse
Verwendung von Abstract Class und Interface in Java richtig
[GCD] Grundlagen der DispatchQueue-Klasse
Zusammenfassung der Verwendung von ButterKnife
Bei Verwendung des Konstruktors der Date-Klasse von Java wird das Datum um 1900 vorverlegt.
[Java] Komparator der Collection-Klasse
Falle der Klasse asList of Arrays
Ratenbegrenzung mit RateLimiter of Resilience4j
Java-Lernnotiz (abstrakte Klasse)
Zusammenfassung der "abstrakten Schnittstellenunterschiede"
Zusammenfassung der Java Math Klasse
Warum eine abstrakte Klasse implementieren (Abstract)
[Java] Vorsichtsmaßnahmen beim Erstellen eines Prozesses, der eine Methode der Abstract-Klasse mit DI aus einer untergeordneten Klasse aufruft
Abrufen des Datums ohne Verwendung der Kalenderklasse
Unterschied zwischen Schnittstelle und abstrakter Klasse
Aufzählung von Kombinationsmustern mit List
Entwicklung von Flink mit der DataStream-API
Validierung von Protokollnachrichten mit mockito
Umgang mit Zeitzonen mit Java
Verschiedene Methoden der String-Klasse
Implementierung der Validierung mit regulären Ausdrücken
Anwendungsbeispiel für Entwurfsmuster (Nr. 1)
Erfassung von Standortinformationen mit FusedLocationProviderClient
Zusammenfassung der objektorientierten Programmierung mit Java
Ich habe versucht, Google HttpClient von Java zu verwenden
[Java] Wie man mit der String-Klasse an die Spitze eines bestimmten Strings kommt
Zeigen Sie den japanischen Kalender und Tag mit der Java8-Standardklasse an