Eine abstrakte Klasse ist eine Klasse, die in Java über das Schlüsselwort „Abstract“ deklariert wird. Abstrakte Klassen sind ein Konzept in einem der vier Prinzipien der objektorientierten Programmierung (OOP), das als „Vererbung“ bezeichnet wird. Vererbung bezieht sich auf eine Funktion von Java-Klassen, bei der eine als „Unterklasse“ bezeichnete Klasse alle Eigenschaften der Klasse erbt. Die übergeordnete Klasse wird oft als „Superklasse“ bezeichnet.
In Java bezieht sich eine abstrakte Klasse auf eine Basis-Superklasse, von der andere Unterklassen erben können. Es kann sowohl abstrakte als auch nicht abstrakte Methoden enthalten.
Schritt 1 – Identifizieren Sie die Methoden in der Klasse, die über eine Standardimplementierung oder keine Implementierung verfügen.
Schritt 2 – Entfernen Sie die Implementierung dieser Methoden.
Schritt 3 – Fügen Sie das abstrakte Schlüsselwort zur Klassendeklaration hinzu.
Schritt 4 – Fügen Sie das abstrakte Schlüsselwort zur in Schritt 2 geänderten Methodendeklaration hinzu.
Schritt 5 – Wenn die Klasse Instanzvariablen hat, die initialisiert werden müssen, fügen Sie einen Konstruktor hinzu, um sie zu initialisieren.
Schritt 6 – Aktualisieren Sie alle Unterklassen der abstrakten Klasse, um abstrakte Methoden zu implementieren oder sich selbst abstrakt zu machen.
Sehen wir uns die Syntax zum Instanziieren abstrakter Klassen in Java an -
// Abstract Class abstract class Shape { public abstract void draw(); }
Da abstrakte Klassen unvollständige Klassen sind, können sie nicht direkt mit dem Schlüsselwort „new“ instanziiert werden.
Konkrete Unterklassen – Um eine mehrdeutige oder unvollständige abstrakte Klasse korrekt zu instanziieren, besteht die Möglichkeit, eine konkrete Unterklasse zu verwenden. Durch die nahtlose Erweiterung von dieser übergeordneten Abstraktion und die Implementierung aller ihrer Methodenanforderungen können Benutzer diese neu instanziierte Unterklasse erfolgreich erstellen und implementieren, ohne Fehler oder Inkonsistenzen in ihrem Betrieb.
Lambda-Ausdruck – Um ein Objekt aus einer abstrakten Klasse zu erstellen, haben Sie eine andere Möglichkeit – den Lambda-Ausdruck zu verwenden, der die Implementierung für alle seine Abstraktionen bereitstellt. Diese Lambda-Erstellung wird dann basierend auf diesen Signaturen einer kompatiblen Funktionsschnittstellenvariablen zugewiesen.
Sehen wir uns einen Beispielcodeausschnitt an, um die Verwendung abstrakter Klassen zu verstehen. Das erste Szenario stellt Code mit nicht abstrakten Klassen bereit.
class Shape { public void printName() { System.out.println("I'm a shape"); } public float area() { return 0; } public void printDetails() { this.printName(); System.out.println("... and my area is " + this.area()); } } class Circle extends Shape { private float radius; public Circle(float radius) { this.radius = radius; } public void printName() { System.out.println("I'm a circle"); } public float area() { return (float) (Math.PI * Math.pow(radius, 2)); } } class Rectangle extends Shape { private float length; private float width; public Rectangle(float length, float width) { this.length = length; this.width = width; } public void printName() { System.out.println("I'm a rectangle"); } public float area() { return length * width; } } public class Main { public static void main(String[] args) { Shape[] shapes = { new Circle(3.5f), new Rectangle(4.0f, 5.0f) }; for (Shape shape : shapes) { shape.printDetails(); } } }
I'm a circle ... and my area is 38.48451 I'm a rectangle ... and my area is 20.0
Sowohl die Circle- als auch die Rechteck-Klasse erben die Methoden printName(), area() und printDetails() von der Superklasse „Shape“. Allerdings überschreibt keine der Klassen die Methode „area()“, um eine eigene Implementierung bereitzustellen.
Durch Aufrufen der printDetails()-Methode des Circle-Objekts lautet die Ausgabe „Ich bin ein Kreis ... und meine Fläche beträgt 38,48451“. Ebenso wird beim Aufruf der printDetails()-Methode für ein Rechteckobjekt Folgendes ausgegeben: „Ich bin ein Rechteck ... und meine Fläche beträgt 20,0“. Dadurch wird sichergestellt, dass die Ausgabe die richtige Form und den entsprechenden Bereich entsprechend der spezifischen Implementierung in jeder Klasse widerspiegelt
// With abstract class abstract class Shape { public abstract void printName(); public abstract float area(); public void printDetails() { this.printName(); System.out.println("... and my area is " + this.area()); } } // Concrete class class Circle extends Shape { private float radius; public Circle(float radius) { this.radius = radius; } public void printName() { System.out.print("I'm a circle"); } public float area() { return (float) (Math.PI * Math.pow(radius, 2)); } } // Concrete class class Rectangle extends Shape { private float length; private float width; public Rectangle(float length, float width) { this.length = length; this.width = width; } public void printName() { System.out.print("I'm a rectangle"); } public float area() { return length * width; } } // Main class public class Main { public static void main(String[] args) { Shape[] shapes = { new Circle(10), new Rectangle(5, 10) }; for (Shape shape : shapes) { shape.printDetails(); } } }
I'm a circle... and my area is 314.15927 I'm a rectangle... and my area is 50.0
Im aktualisierten Code oben implementieren die Klassen Circle und Rechteck die abstrakten Methoden printName() und area(), die in der abstrakten Klasse „Shape“ definiert sind. Die printDetails()-Methode in der Shape-Klasse kann diese Methoden verwenden, um den Namen der Form und ihren jeweiligen Bereich auszudrucken.
Indem wir Shape zu einer abstrakten Klasse machen und abstrakte Methoden definieren, stellen wir sicher, dass jede Klasse, die die Shape-Klasse erweitert, ihre eigene Implementierung für die Methoden printName() und area() bereitstellen muss.
interface Nameable { String getName(); } abstract class Shape { private Nameable nameable; public Shape(Nameable nameable) { this.nameable = nameable; } public abstract float area(); public void printDetails() { System.out.println("I'm a " + nameable.getName() + " ... and my area is " + this.area()); } } class Circle extends Shape { private float radius; public Circle(float radius) { super(() -> "circle"); this.radius = radius; } @Override public float area() { return (float) (Math.PI * Math.pow(radius, 2)); } } class Rectangle extends Shape { private float width; private float height; public Rectangle(float width, float height) { super(() -> "rectangle"); this.width = width; this.height = height; } @Override public float area() { return width * height; } } public class Main { public static void main(String[] args) { Shape[] shapes = { new Circle(10), new Rectangle(5, 10) }; for (Shape shape : shapes) { shape.printDetails(); } } }
I'm a circle ... and my area is 314.15927 I'm a rectangle ... and my area is 50.0
Im neuesten Update dieses Codes haben wir eine verbesserte Möglichkeit eingeführt, Shape als abstrakte Klasse anzugeben und gleichzeitig die Funktion getName() zu internalisieren. Eine weitere Verbesserung besteht in der Integration der printName-Methode, die die Daten von getName() erfolgreich nutzt, um den Namen jeder entsprechenden Form anzuzeigen. Für die Unterklassen „Circle“ und „Rechteck“ überschreiben sie jetzt den entsprechenden getName mithilfe eines Lambda-Ausdrucks, sodass die erwartete Form genau identifiziert wird.
Zusammenfassend lässt sich sagen, dass eine abstrakte Klasse nur über ihre Basisunterklasse instanziiert werden kann, nicht direkt. Dies ist ein vererbtes Konzept.
Der Hauptgrund dafür ist, dass eine abstrakte Klasse keine vollständige Implementierung ihrer Methoden und Objekte ist, sondern von Unterklassen verwendet wird, um diese zu erben.
Das obige ist der detaillierte Inhalt vonWie instanziiere ich eine abstrakte Klasse in Java?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!