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.
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.
https://paiza.io/projects/Iwnh9NgDAaxPSZC36uZqsw
Klassenstruktur:
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.
https://paiza.io/projects/Xs-iNK2-SYDnlYIp1oWF3w
Klassenstruktur:
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.
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
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.
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.
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.
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.
Klassenstruktur:
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());
}
}
Klassenstruktur:
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.
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