Was ist eine "abstrakte Klasse" in Java?
Was ist eine "abstrakte Klasse" in Java?
Antworten:
Eine abstrakte Klasse ist eine Klasse, die nicht instanziiert werden kann. Eine abstrakte Klasse wird durch Erstellen einer Unterklasse erbt verwendet , die können instanziiert werden. Eine abstrakte Klasse erledigt einige Dinge für die erbende Unterklasse:
Hier ist ein Beispiel:
abstract public class AbstractClass
{
abstract public void abstractMethod();
public void implementedMethod() { System.out.print("implementedMethod()"); }
final public void finalMethod() { System.out.print("finalMethod()"); }
}
Beachten Sie, dass "abstractMethod ()" keinen Methodenkörper hat. Aus diesem Grund können Sie Folgendes nicht tun:
public class ImplementingClass extends AbstractClass
{
// ERROR!
}
Es gibt keine Methode, die implementiert abstractMethod()
! Die JVM kann also nicht wissen, was sie tun soll, wenn sie so etwas bekommt new ImplementingClass().abstractMethod()
.
Hier ist eine korrekte ImplementingClass
.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
}
Beachten Sie, dass Sie müssen nicht definieren implementedMethod()
oder finalMethod()
. Sie wurden bereits von definiert AbstractClass
.
Hier ist noch eine richtige ImplementingClass
.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
In diesem Fall haben Sie überschrieben implementedMethod()
.
Aufgrund des final
Schlüsselworts ist Folgendes jedoch nicht möglich.
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
public void finalMethod() { System.out.print("ERROR!"); }
}
Sie können dies nicht tun, da die Implementierung von finalMethod()
in AbstractClass
als die endgültige Implementierung von markiert ist finalMethod()
: Es werden niemals andere Implementierungen zugelassen.
Jetzt können Sie auch eine abstrakte Klasse implementieren zweimal:
public class ImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("abstractMethod()"); }
public void implementedMethod() { System.out.print("Overridden!"); }
}
// In a separate file.
public class SecondImplementingClass extends AbstractClass
{
public void abstractMethod() { System.out.print("second abstractMethod()"); }
}
Jetzt könnten Sie irgendwo eine andere Methode schreiben.
public tryItOut()
{
ImplementingClass a = new ImplementingClass();
AbstractClass b = new ImplementingClass();
a.abstractMethod(); // prints "abstractMethod()"
a.implementedMethod(); // prints "Overridden!" <-- same
a.finalMethod(); // prints "finalMethod()"
b.abstractMethod(); // prints "abstractMethod()"
b.implementedMethod(); // prints "Overridden!" <-- same
b.finalMethod(); // prints "finalMethod()"
SecondImplementingClass c = new SecondImplementingClass();
AbstractClass d = new SecondImplementingClass();
c.abstractMethod(); // prints "second abstractMethod()"
c.implementedMethod(); // prints "implementedMethod()"
c.finalMethod(); // prints "finalMethod()"
d.abstractMethod(); // prints "second abstractMethod()"
d.implementedMethod(); // prints "implementedMethod()"
d.finalMethod(); // prints "finalMethod()"
}
Beachten Sie, dass , obwohl wir erklären b
eine AbstractClass
Art, zeigt es "Overriden!"
. Dies liegt daran, dass das von uns instanziierte Objekt tatsächlich ein Objekt war ImplementingClass
, das implementedMethod()
natürlich überschrieben wird. (Möglicherweise haben Sie dies als Polymorphismus bezeichnet gesehen.)
Wenn wir auf ein Mitglied zugreifen möchten, das für eine bestimmte Unterklasse spezifisch ist, müssen wir zuerst auf diese Unterklasse zurückgreifen:
// Say ImplementingClass also contains uniqueMethod()
// To access it, we use a cast to tell the runtime which type the object is
AbstractClass b = new ImplementingClass();
((ImplementingClass)b).uniqueMethod();
Schließlich können Sie Folgendes nicht tun:
public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass
{
... // implementation
}
Es kann jeweils nur eine Klasse erweitert werden. Wenn Sie mehrere Klassen erweitern müssen, müssen diese Schnittstellen sein. Du kannst das:
public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB
{
... // implementation
}
Hier ist eine Beispielschnittstelle:
interface InterfaceA
{
void interfaceMethod();
}
Dies ist im Grunde das gleiche wie:
abstract public class InterfaceA
{
abstract public void interfaceMethod();
}
Der einzige Unterschied besteht darin, dass der Compiler auf dem zweiten Weg nicht weiß, dass es sich tatsächlich um eine Schnittstelle handelt. Dies kann nützlich sein, wenn Sie möchten, dass Benutzer nur Ihre Schnittstelle und keine anderen implementieren. Als allgemeine Faustregel für Anfänger sollten Sie Ihre abstrakte Klasse jedoch wahrscheinlich zu einer Schnittstelle machen, wenn sie nur über abstrakte Methoden verfügt.
Folgendes ist illegal:
interface InterfaceB
{
void interfaceMethod() { System.out.print("ERROR!"); }
}
Sie können keine Methoden in einer Schnittstelle implementieren. Wenn Sie also zwei verschiedene Schnittstellen implementieren, können die verschiedenen Methoden in diesen Schnittstellen nicht kollidieren. Da alle Methoden in einer Schnittstelle abstrakt sind, müssen Sie die Methode implementieren. Da Ihre Methode die einzige Implementierung im Vererbungsbaum ist, weiß der Compiler, dass er Ihre Methode verwenden muss.
c.implementedMethod()
"Overriden!" Drucken? SecondImplementingClass
überschreibt nicht implementedMethod()
.
Eine Java-Klasse wird unter folgenden Bedingungen abstrakt:
1. Mindestens eine der Methoden ist als abstrakt gekennzeichnet:
public abstract void myMethod()
In diesem Fall zwingt Sie der Compiler, die gesamte Klasse als abstrakt zu markieren.
2. Die Klasse ist als abstrakt markiert:
abstract class MyClass
Wie bereits gesagt: Wenn Sie eine abstrakte Methode haben, zwingt Sie der Compiler, die gesamte Klasse als abstrakt zu markieren. Aber selbst wenn Sie keine abstrakte Methode haben, können Sie die Klasse dennoch als abstrakt markieren.
Allgemeiner Gebrauch:
Eine übliche Verwendung von abstrakten Klassen besteht darin, einen Überblick über eine Klasse zu geben, der einer Schnittstelle ähnlich ist. Im Gegensatz zu einer Schnittstelle kann sie jedoch bereits Funktionen bereitstellen, dh einige Teile der Klasse sind implementiert und einige Teile werden nur mit einer Methodendeklaration umrissen. ("abstrakt")
Eine abstrakte Klasse kann nicht instanziiert werden, aber Sie können eine konkrete Klasse basierend auf einer abstrakten Klasse erstellen, die dann instanziiert werden kann. Dazu müssen Sie von der abstrakten Klasse erben und die abstrakten Methoden überschreiben, dh implementieren.
abstract
Schlüsselwort alles ist, was für eine abstrakte Klasse erforderlich ist. Eine konkrete Klasse kann jedoch keine abstract
Methode enthalten . Wenn Ihre Klasse eine abstract
Methode hat, muss sie abstract
dem Compiler als Klasse deklariert werden .
Eine Klasse, die mit dem Schlüsselwort abstract deklariert wird, heißt abstract class
. Bei der Abstraktion werden die Details der Datenimplementierung ausgeblendet und dem Benutzer nur Funktionen angezeigt. Mit Abstraktion können Sie sich darauf konzentrieren, was das Objekt tut, anstatt wie es es tut.
Hauptsachen der abstrakten Klasse
Eine abstrakte Klasse kann abstrakte Methoden enthalten oder nicht. Es kann nicht abstrakte Methoden geben.
Eine abstrakte Methode ist eine Methode, die ohne Implementierung deklariert wird (ohne geschweifte Klammern und gefolgt von einem Semikolon).
Ex : abstract void moveTo(double deltaX, double deltaY);
Wenn eine Klasse mindestens eine abstrakte Methode hat, muss diese Klasse abstrakt sein
Abstrakte Klassen dürfen nicht instanziiert werden (Sie dürfen kein Objekt der abstrakten Klasse erstellen).
Um eine abstrakte Klasse zu verwenden, müssen Sie sie von einer anderen Klasse erben. Stellen Sie Implementierungen für alle darin enthaltenen abstrakten Methoden bereit.
Wenn Sie eine abstrakte Klasse erben, müssen Sie Implementierungen für alle darin enthaltenen abstrakten Methoden bereitstellen.
Abstrakte Klasse
deklarieren Wenn Sie das abstract
Schlüsselwort vor der Klasse während der Deklaration angeben, wird sie abstrakt. Schauen Sie sich den folgenden Code an:
abstract class AbstractDemo{ }
Abstrakte Methode
deklarieren Wenn Sie das abstract
Schlüsselwort angeben, bevor die Methode während der Deklaration abstrakt wird. Schauen Sie sich den Code unten an,
abstract void moveTo();//no body
Warum wir Klassen abstrahieren müssen
In einer objektorientierten Zeichenanwendung können Sie Kreise, Rechtecke, Linien, Bezier-Kurven und viele andere grafische Objekte zeichnen. Diese Objekte haben alle bestimmte Zustände (z. B. Position, Ausrichtung, Linienfarbe, Füllfarbe) und Verhaltensweisen (z. B. Verschieben, Drehen, Ändern der Größe, Zeichnen) gemeinsam. Einige dieser Zustände und Verhaltensweisen sind für alle Grafikobjekte gleich (z. B. Füllfarbe, Position und Verschieben nach). Andere erfordern eine andere Implementierung (z. B. Größe ändern oder zeichnen). Alle Grafikobjekte müssen in der Lage sein, sich selbst zu zeichnen oder ihre Größe zu ändern. Sie unterscheiden sich lediglich darin, wie sie dies tun.
Dies ist eine perfekte Situation für eine abstrakte Oberklasse. Sie können die Ähnlichkeiten nutzen und alle Grafikobjekte deklarieren, die von demselben abstrakten übergeordneten Objekt (z. GraphicObject
B. :) geerbt werden sollen ( siehe folgende Abbildung).
Zunächst deklarieren Sie eine abstrakte Klasse, GraphicObject
um Elementvariablen und Methoden bereitzustellen, die von allen Unterklassen vollständig gemeinsam genutzt werden, z. B. die aktuelle Position und die moveTo-Methode. GraphicObject
deklarierte auch abstrakte Methoden wie Zeichnen oder Ändern der Größe, die von allen Unterklassen implementiert werden müssen, aber auf unterschiedliche Weise implementiert werden müssen. Die GraphicObject
Klasse kann ungefähr so aussehen:
abstract class GraphicObject {
void moveTo(int x, int y) {
// Inside this method we have to change the position of the graphic
// object according to x,y
// This is the same in every GraphicObject. Then we can implement here.
}
abstract void draw(); // But every GraphicObject drawing case is
// unique, not common. Then we have to create that
// case inside each class. Then create these
// methods as abstract
abstract void resize();
}
Die Verwendung von abstrakte Methode in Unterklassen
Jede nicht abstrakte Subklassen GraphicObject
, wie Circle
und Rectangle
müssen bieten Implementierungen für die draw
und resize
Methoden.
class Circle extends GraphicObject {
void draw() {
//Add to some implementation here
}
void resize() {
//Add to some implementation here
}
}
class Rectangle extends GraphicObject {
void draw() {
//Add to some implementation here
}
void resize() {
//Add to some implementation here
}
}
Innerhalb der main
Methode können Sie alle Methoden wie folgt aufrufen:
public static void main(String args[]){
GraphicObject c = new Circle();
c.draw();
c.resize();
c.moveTo(4,5);
}
Möglichkeiten zur Abstraktion in Java
Es gibt zwei Möglichkeiten, um in Java eine Abstraktion zu erreichen
Abstrakte Klasse mit Konstruktoren, Datenelementen, Methoden usw.
abstract class GraphicObject {
GraphicObject (){
System.out.println("GraphicObject is created");
}
void moveTo(int y, int x) {
System.out.println("Change position according to "+ x+ " and " + y);
}
abstract void draw();
}
class Circle extends GraphicObject {
void draw() {
System.out.println("Draw the Circle");
}
}
class TestAbstract {
public static void main(String args[]){
GraphicObject grObj = new Circle ();
grObj.draw();
grObj.moveTo(4,6);
}
}
Ausgabe:
GraphicObject is created
Draw the Circle
Change position according to 6 and 4
Denken Sie an zwei Regeln:
Wenn die Klasse nur wenige abstrakte und nur wenige konkrete Methoden enthält, deklarieren Sie sie als abstract
Klasse.
Wenn die Klasse nur abstrakte Methoden hat, deklarieren Sie sie als interface
.
Verweise:
Es ist eine Klasse, die nicht instanziiert werden kann und die Implementierung von Klassen zwingt, möglicherweise abstrakte Methoden zu implementieren, die darin beschrieben werden.
Einfach gesagt, Sie können sich eine abstrakte Klasse als eine Schnittstelle mit etwas mehr Funktionen vorstellen.
Sie können keine Schnittstelle instanziieren, die auch für eine abstrakte Klasse gilt.
Auf Ihrer Schnittstelle können Sie einfach die Methodenheader definieren und ALLE Implementierer sind gezwungen , alle zu implementieren . In einer abstrakten Klasse können Sie auch Ihre Methodenheader definieren, aber hier können Sie - im Unterschied zur Schnittstelle - auch den Hauptteil (normalerweise eine Standardimplementierung) der Methode definieren. Wenn andere Klassen Ihre abstrakte Klasse erweitern (beachten Sie, dass sie nicht implementiert werden und Sie daher auch nur eine abstrakte Klasse pro untergeordnete Klasse haben können), müssen sie nicht alle Methoden Ihrer abstrakten Klasse implementieren, es sei denn, Sie haben eine abstrakte Methode angegeben ( In diesem Fall funktioniert es wie bei Schnittstellen. Sie können den Methodenkörper nicht definieren.
public abstract class MyAbstractClass{
public abstract void DoSomething();
}
Andernfalls können die "Erben" für normale Methoden einer abstrakten Klasse entweder nur das Standardverhalten verwenden oder es wie gewohnt überschreiben.
Beispiel:
public abstract class MyAbstractClass{
public int CalculateCost(int amount){
//do some default calculations
//this can be overriden by subclasses if needed
}
//this MUST be implemented by subclasses
public abstract void DoSomething();
}
Aus der Orakel- Dokumentation
Abstrakte Methoden und Klassen:
Eine abstrakte Klasse ist eine Klasse, die als abstrakt deklariert ist. Sie kann abstrakte Methoden enthalten oder nicht
Abstrakte Klassen können nicht instanziiert, aber in Unterklassen unterteilt werden
Eine abstrakte Methode ist eine Methode , die ohne eine Implementierung (durch ein Semikolon ohne Klammern und folgte) erklärt wird, wie folgt aus :
abstract void moveTo(double deltaX, double deltaY);
Wenn eine Klasse abstrakte Methoden enthält, muss die Klasse selbst als abstrakt deklariert werden, wie in:
public abstract class GraphicObject {
// declare fields
// declare nonabstract methods
abstract void draw();
}
Wenn eine abstrakte Klasse in eine Unterklasse unterteilt ist, stellt die Unterklasse normalerweise Implementierungen für alle abstrakten Methoden in ihrer übergeordneten Klasse bereit. Ist dies nicht der Fall, muss die Unterklasse ebenfalls als abstrakt deklariert werden .
Da abstract classes
und interfaces
verwandt sind, werfen Sie einen Blick auf die folgenden SE-Fragen:
Was ist der Unterschied zwischen einer Schnittstelle und einer abstrakten Klasse?
Wie hätte ich den Unterschied zwischen einer Interface- und einer Abstract-Klasse erklären sollen?
Hier erhalten Sie Ihre Antworten:
Abstrakte Klasse vs Schnittstelle in Java
Kann eine abstrakte Klasse eine endgültige Methode haben?
Übrigens - das sind Fragen, die Sie kürzlich gestellt haben. Denken Sie über eine neue Frage nach, um Ihren Ruf aufzubauen ...
Bearbeiten:
Gerade festgestellt, dass die Poster dieser und der referenzierten Fragen den gleichen oder zumindest einen ähnlichen Namen haben, die Benutzer-ID jedoch immer unterschiedlich ist. Entweder gibt es ein technisches Problem, dass Keyur Probleme hat, sich erneut anzumelden und die Antworten auf seine Fragen zu finden, oder dies ist eine Art Spiel, um die SO-Community zu unterhalten;)
Kleine Ergänzung zu all diesen Beiträgen.
Manchmal möchten Sie möglicherweise eine Klasse deklarieren und wissen dennoch nicht, wie alle Methoden definiert werden sollen, die zu dieser Klasse gehören. Beispielsweise möchten Sie möglicherweise eine Klasse namens Writer deklarieren und eine Member-Methode namens write () in sie aufnehmen . Sie wissen jedoch nicht, wie man write () codiert , da es für jeden Typ von Writer-Geräten unterschiedlich ist. Natürlich planen Sie, dies zu handhaben, indem Sie eine Unterklasse von Writer ableiten, z. B. Drucker, Festplatte, Netzwerk und Konsole.
Eine abstrakte Klasse kann nicht direkt instanziiert werden, sondern muss abgeleitet werden, um verwendbar zu sein. Eine Klasse MUSS abstrakt sein, wenn sie abstrakte Methoden enthält: entweder direkt
abstract class Foo {
abstract void someMethod();
}
oder indirekt
interface IFoo {
void someMethod();
}
abstract class Foo2 implements IFoo {
}
Eine Klasse kann jedoch abstrakt sein, ohne abstrakte Methoden zu enthalten. Dies ist ein Weg, um eine direkte Instanziierung zu verhindern, z
abstract class Foo3 {
}
class Bar extends Foo3 {
}
Foo3 myVar = new Foo3(); // illegal! class is abstract
Foo3 myVar = new Bar(); // allowed!
Der letztere Stil von abstrakten Klassen kann verwendet werden, um "schnittstellenähnliche" Klassen zu erstellen. Im Gegensatz zu Schnittstellen darf eine abstrakte Klasse nicht abstrakte Methoden und Instanzvariablen enthalten. Sie können dies verwenden, um einige Basisfunktionen zum Erweitern von Klassen bereitzustellen.
Ein weiteres häufiges Muster besteht darin, die Hauptfunktionalität in der abstrakten Klasse zu implementieren und einen Teil des Algorithmus in einer abstrakten Methode zu definieren, die von einer erweiterten Klasse implementiert werden soll. Dummes Beispiel:
abstract class Processor {
protected abstract int[] filterInput(int[] unfiltered);
public int process(int[] values) {
int[] filtered = filterInput(values);
// do something with filtered input
}
}
class EvenValues extends Processor {
protected int[] filterInput(int[] unfiltered) {
// remove odd numbers
}
}
class OddValues extends Processor {
protected int[] filterInput(int[] unfiltered) {
// remove even numbers
}
}
public abstract class Place {
String Name;
String Postcode;
String County;
String Area;
Place () {
}
public static Place make(String Incoming) {
if (Incoming.length() < 61) return (null);
String Name = (Incoming.substring(4,26)).trim();
String County = (Incoming.substring(27,48)).trim();
String Postcode = (Incoming.substring(48,61)).trim();
String Area = (Incoming.substring(61)).trim();
Place created;
if (Name.equalsIgnoreCase(Area)) {
created = new Area(Area,County,Postcode);
} else {
created = new District(Name,County,Postcode,Area);
}
return (created);
}
public String getName() {
return (Name);
}
public String getPostcode() {
return (Postcode);
}
public String getCounty() {
return (County);
}
public abstract String getArea();
}
Eine abstrakte Klasse ist eine Klasse, die als abstrakt deklariert ist - sie kann abstrakte Methoden enthalten oder nicht. Abstrakte Klassen können nicht instanziiert, aber in Unterklassen unterteilt werden.
Mit anderen Worten, eine Klasse, die mit dem Schlüsselwort abstract deklariert ist, wird in Java als abstrakte Klasse bezeichnet. Es kann abstrakte (Methode ohne Körper) und nicht abstrakte Methoden (Methode mit Körper) haben.
Wichtiger Hinweis: - Abstrakte Klassen können nicht zum Instanziieren von Objekten verwendet werden, sondern zum Erstellen von Objektreferenzen, da Javas Ansatz zum Laufzeitpolymorphismus durch die Verwendung von Superklassenreferenzen implementiert wird. Daher muss es möglich sein, einen Verweis auf eine abstrakte Klasse zu erstellen, damit auf ein Unterklassenobjekt verwiesen werden kann. Sie werden diese Funktion im folgenden Beispiel sehen
abstract class Bike{
abstract void run();
}
class Honda4 extends Bike{
void run(){
System.out.println("running safely..");
}
public static void main(String args[]){
Bike obj = new Honda4();
obj.run();
}
}
Eine abstrakte Klasse ist eine Klasse, die nicht vollständig implementiert ist, aber eine Art Blaupause für Unterklassen bietet. Es kann teilweise implementiert werden, indem es vollständig definierte konkrete Methoden enthält, aber es kann auch abstrakte Methoden enthalten. Dies sind Methoden mit einer Signatur, aber ohne Methodenkörper. Jede Unterklasse muss für jede abstrakte Methode einen Body definieren, andernfalls muss auch dieser als abstrakt deklariert werden. Da abstrakte Klassen nicht instanziiert werden können, müssen sie um mindestens eine Unterklasse erweitert werden, um verwendet zu werden. Stellen Sie sich die abstrakte Klasse als generische Klasse vor, und die Unterklassen dienen dazu, die fehlenden Informationen auszufüllen.
Es wird nichts unternommen, sondern nur eine gemeinsame Vorlage bereitgestellt, die für die Unterklasse freigegeben wird