it-swarm.com.de

Abstrakte Klasse in Java

Was ist eine "abstrakte Klasse" in Java?

249
keyur

Eine abstrakte Klasse ist eine Klasse, die nicht instanziiert werden kann. Eine abstrakte Klasse wird verwendet, indem eine erbende Unterklasse erstellt wird, die can instanziiert werden kann. Eine abstrakte Klasse führt einige Dinge für die erbliche Unterklasse aus:

  1. Definieren Sie Methoden, die von der erbenden Unterklasse verwendet werden können.
  2. Definieren Sie abstrakte Methoden, die die erbende Unterklasse implementieren muss.
  3. Stellen Sie eine gemeinsame Schnittstelle bereit, die den Austausch der Unterklasse mit allen anderen Unterklassen ermöglicht.

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 Methodentext besitzt. Aus diesem Grund können Sie Folgendes nicht tun:

public class ImplementingClass extends AbstractClass
{
    // ERROR!
}

Es gibt keine Methode, die abstractMethod() implementiert! Die JVM kann also nicht wissen, was sie tun soll, wenn sie etwas wie new ImplementingClass().abstractMethod() bekommt.

Hier ist eine korrekte ImplementingClass.

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
}

Beachten Sie, dass Sie nicht implementedMethod() oder finalMethod() definieren müssen. Sie wurden bereits von AbstractClass definiert.

Hier ist noch ein richtiger 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 implementedMethod() überschrieben.

Aufgrund des Schlüsselworts final ist jedoch Folgendes 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 endgültige Implementierung von finalMethod() markiert ist: Es sind niemals andere Implementierungen zulässig.

Jetzt können Sie auch eine abstrakte Klasse zweimal implementieren:

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önnte man 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 b als AbstractClass-Typ deklariert haben, "Overriden!" angezeigt wird. Dies liegt daran, dass das von uns instanziierte Objekt tatsächlich ein ImplementingClass war, dessen implementedMethod() natürlich überschrieben wird. (Möglicherweise haben Sie dies als Polymorphismus bezeichnet.)

Wenn wir auf ein bestimmtes Mitglied einer bestimmten Unterklasse zugreifen möchten, 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();
}

Das ist im Grunde dasselbe wie:

abstract public class InterfaceA
{
    abstract public void interfaceMethod();
}

Der einzige Unterschied ist, dass der zweite Weg den Compiler nicht wissen lässt, dass es sich tatsächlich um eine Schnittstelle handelt. Dies kann nützlich sein, wenn die Benutzer nur Ihre Schnittstelle implementieren sollen und keine anderen. Als allgemeine Anfängerregel gilt: Wenn Ihre abstrakte Klasse nur abstrakte Methoden enthält, sollten Sie sie wahrscheinlich zu einer Schnittstelle machen.

Folgendes ist illegal:

interface InterfaceB
{
    void interfaceMethod() { System.out.print("ERROR!"); }
}

Sie können keine Methoden in einer Schnittstelle implementieren. Das heißt, wenn Sie zwei verschiedene Schnittstellen implementieren, können die unterschiedlichen 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 in der Vererbungsstruktur ist, weiß der Compiler, dass er Ihre Methode verwenden muss.

320
Imagist

Eine Java-Klasse wird unter den folgenden Bedingungen abstrakt:

1. Mindestens eine der Methoden ist als abstrakt gekennzeichnet:

public abstract void myMethod()

In diesem Fall zwingt der Compiler Sie, die gesamte Klasse als abstrakt zu markieren.

2. Die Klasse ist als abstrakt markiert:

abstract class MyClass

Wie gesagt: Wenn Sie eine abstrakte Methode haben, zwingt Sie der Compiler, die gesamte Klasse als abstrakt zu markieren. Aber auch wenn Sie keine abstrakte Methode haben, können Sie die Klasse trotzdem als abstrakt markieren.

Allgemeiner Gebrauch:

Abstrakte Klassen werden häufig verwendet, um einen Überblick über eine Klasse zu geben, die einem Interface ähnelt. Im Gegensatz zu einer Schnittstelle kann sie jedoch bereits Funktionalität bereitstellen, d. H. Einige Teile der Klasse werden implementiert und einige Teile werden nur mit einer Methodendeklaration beschrieben. ("abstrakt")

Eine abstrakte Klasse kann nicht instanziiert werden. Sie können jedoch eine konkrete Klasse auf der Grundlage einer abstrakten Klasse erstellen, die dann instanziiert werden kann. Dazu müssen Sie von der abstrakten Klasse erben und die abstrakten Methoden überschreiben, d. H. Implementieren. 

67
Daniel Rikowski

Eine mit dem Schlüsselwort abstract deklarierte Klasse wird als abstract class..__ bezeichnet. Bei der Abstraktion werden die Datenimplementierungsdetails ausgeblendet und dem Benutzer nur die Funktionalität angezeigt. Mit der Abstraktion können Sie sich auf das konzentrieren, was das Objekt macht, anstatt darauf, wie es funktioniert.

Hauptsachen der abstrakten Klasse

  • Eine abstrakte Klasse kann abstrakte Methoden enthalten oder nicht. Es können nicht abstrakte Methoden vorhanden sein.

    Eine abstrakte Methode ist eine Methode, die ohne -Implementierung (ohne geschweifte Klammern und gefolgt von einem Semikolon) deklariert wird.

    zB: abstract void moveTo(double deltaX, double deltaY);

  • Wenn eine Klasse mindestens eine abstrakte Methode hat, muss diese Klasse abstrakt sein 

  • Abstrakte Klassen können nicht instanziiert werden (Sie dürfen keine Objekte der abstrakten Klasse erstellen)

  • Um eine abstrakte Klasse verwenden zu können, müssen Sie sie von einer anderen Klasse erben. Stellen Sie Implementierungen für alle abstrakten Methoden bereit. 

  • Wenn Sie eine abstrakte Klasse erben, müssen Sie alle abstrakten Methoden darin implementieren.

Declare abstract class Die Angabe eines abstract-Schlüsselworts vor der Klasse während der Deklaration macht sie abstrakt. Schauen Sie sich den Code unten an:

abstract class AbstractDemo{ }

Abstrakte Methode deklarieren Die Angabe eines abstract-Schlüsselworts vor der Methode während der Deklaration macht sie abstrakt. Schauen Sie sich den Code unten an, 

abstract void moveTo();//no body

Warum müssen wir Klassen abstrahieren 

In einer objektorientierten Zeichenanwendung können Sie Kreise, Rechtecke, Linien, Bézier-Kurven und viele andere Grafikobjekte zeichnen. Alle diese Objekte haben bestimmte Zustände (z. B. Position, Ausrichtung, Linienfarbe, Füllfarbe) und Verhalten (z. B.: Verschieben, Drehen, Ändern der Größe und Zeichnen) gemeinsam. Einige dieser Zustände und Verhaltensweisen sind für alle Grafikobjekte gleich (z. B. Füllfarbe, Position und Verschieben-zu). Andere erfordern eine andere Implementierung (zum Beispiel: Größe ändern oder zeichnen). Alle Grafikobjekte müssen in der Lage sein, selbst zu zeichnen oder ihre Größe zu ändern, sie unterscheiden sich lediglich in der Art und Weise, wie sie es tun. 

Dies ist eine perfekte Situation für eine abstrakte Superklasse. Sie können die Ähnlichkeiten ausnutzen und alle Grafikobjekte so deklarieren, dass sie von demselben abstrakten übergeordneten Objekt (z. B. GraphicObject) erben, wie in der folgenden Abbildung gezeigt .  enter image description here

Zuerst deklarieren Sie eine abstrakte Klasse, GraphicObject, um Mitgliedsvariablen und -methoden bereitzustellen, die von allen Unterklassen vollständig verwendet werden, z. B. der aktuellen Position und der moveTo-Methode. GraphicObject deklarierte auch abstrakte Methoden, wie z. B. draw oder size, 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();
}

Verwendung der abstrakten Methode in Unterklassen Jede nicht abstrakte Unterklasse von GraphicObject, wie Circle und Rectangle, muss Implementierungen für die Methoden draw und resize bereitstellen.

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);   
}

Wege zur Abstraktion in Java 

Es gibt zwei Möglichkeiten, eine Abstraktion in Java zu erreichen

  • Abstrakte Klasse (0 bis 100%)
  • Schnittstelle (100%)

Abstrakte Klasse mit Konstruktoren, Datenmitgliedern, 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

Zwei Regeln beachten:

  • Wenn die Klasse über wenige abstrakte und wenige konkrete Methoden verfügt, deklariert Sie als abstract-Klasse.

  • Wenn die Klasse nur abstrakte Methoden hat, deklarieren Sie sie als interface.

Verweise: 

16
Dev4World

Es ist eine Klasse, die nicht instanziiert werden kann, und zwingt die Implementierung von Klassen, möglicherweise abstrakte Methoden zu implementieren, die sie skizziert.

4
Noon Silk

Hier erhalten Sie Ihre Antworten:

Abstrakte Klasse gegen Schnittstelle in Java

Kann eine abstrakte Klasse eine endgültige Methode haben?

Übrigens - diese Frage haben Sie kürzlich gestellt. Denken Sie über eine neue Frage nach, um sich einen guten Ruf aufzubauen ... 

Bearbeiten:

Ich habe gerade erkannt, dass die Poster dieser und der referenzierten Fragen den gleichen oder zumindest einen ähnlichen Namen haben, aber die Benutzer-ID ist immer unterschiedlich. Es gibt also ein technisches Problem, dass keyur Probleme hat, sich wieder einzuloggen und Antworten auf seine Fragen zu finden, oder dies ist eine Art Spiel, um die SO Community zu unterhalten;)

3
Andreas_D

Einfach ausgedrückt, können Sie sich eine abstrakte Klasse als ein Interface mit etwas mehr Fähigkeiten vorstellen. 

Sie können keine Schnittstelle instanziieren, die auch für eine abstrakte Klasse gilt. 

Auf Ihrer Oberfläche können Sie einfach die Methodenköpfe definieren, und ALLE Implementierer sind gezwungen, alle von ihnen zu implementieren. In einer abstrakten Klasse können Sie auch Ihre Methodenköpfe definieren. Hier können Sie jedoch - zum Unterschied der Schnittstelle - auch den Rumpf (normalerweise eine Standardimplementierung) der Methode definieren. Wenn andere Klassen Ihre abstrakten Klassen erweitern (Hinweis, nicht implementieren und daher auch nur eine abstrakte Klasse pro Klasse), müssen sie nicht alle Ihre Methoden Ihrer abstrakten Klasse implementieren, sofern Sie dies nicht angegeben haben eine abstrakte Methode (in diesem Fall funktioniert sie wie für Schnittstellen, Sie können den Methodenkörper nicht definieren).

public abstract class MyAbstractClass{
  public abstract void DoSomething();
}

Ansonsten können die "Vererbungen" bei normalen Methoden einer abstrakten Klasse wie gewohnt entweder das Standardverhalten verwenden oder es ü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();
}
3
Juri

Von Oracle Dokumentation

Abstrakte Methoden und Klassen:

Eine abstrakte Klasse ist eine als abstrakt deklarierte Klasse. Sie kann abstrakte Methoden enthalten oder nicht

Abstrakte Klassen können nicht instanziiert werden, sie können jedoch Unterklassen enthalten

Eine abstrakte Methode ist eine Methode, die ohne Implementierung deklariert wird (ohne geschweifte Klammern und gefolgt von einem Semikolon), wie folgt:

abstract void moveTo(double deltaX, double deltaY);

Wenn eine Klasse abstrakte Methoden enthält, muss die Klasse selbst als abstrakt deklariert werden.

public abstract class GraphicObject {
   // declare fields
   // declare nonabstract methods
   abstract void draw();
}

Wenn eine abstrakte Klasse Unterklasse ist, stellt die Unterklasse normalerweise Implementierungen für alle abstrakten Methoden in ihrer übergeordneten Klasse bereit. Wenn dies nicht der Fall ist, muss die Unterklasse auch als abstrakt deklariert werden.

Da abstract classes und interfaces miteinander zusammenhängen, schauen Sie sich die folgenden SE-Fragen an:

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?

3
Ravindra babu

Lösung - Basisklasse (abstrakt)

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();

}
1

Kleine Ergänzung zu all diesen Beiträgen.

Manchmal möchten Sie vielleicht eine .__ angeben. Klasse und wissen noch nicht, wie alle Methoden, die dazu gehören Klasse. Zum Beispiel möchten Sie vielleicht Deklarieren Sie eine Klasse namens Writer und Fügen Sie eine Member-Methode mit dem Namen .__ ein. schreiben() . Sie wissen jedoch nicht, wie Sie write () codieren sollen, da es .__ ist. für jeden Writer-Typ unterschiedlich Geräte. Natürlich möchten Sie mit .__ umgehen. dies durch Ableiten der Unterklasse von Writer, wie Drucker, Datenträger, Netzwerk und Konsole.

1
adatapost

Eine abstrakte Klasse kann nicht direkt instanziiert werden, muss aber abgeleitet werden, um verwendbar zu sein. Eine KlasseMUSSabstrakt 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. Es ist eine Möglichkeit, eine direkte Instantation 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 abstrakter Klassen kann verwendet werden, um "schnittstellenartige" 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 Erweiterungsklasse 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
    }
}
1
janko

Eine abstrakte Klasse ist eine Klasse, die nicht vollständig implementiert ist, aber für die Unterklassen etwas Blaupause liefert. Es kann teilweise implementiert werden, indem es vollständig definierte konkrete Methoden enthält, es kann jedoch auch abstrakte Methoden enthalten. Hierbei handelt es sich um Methoden mit einer Signatur, aber keinem Methodentext. Jede Unterklasse muss für jede abstrakte Methode einen Rumpf definieren, andernfalls muss sie als abstrakt deklariert werden .. Da abstrakte Klassen nicht instanziiert werden können, müssen sie um mindestens eine Unterklasse erweitert werden, damit sie verwendet werden können. Stellen Sie sich die abstrakte Klasse als generische Klasse vor, und die Unterklassen sind dazu da, die fehlenden Informationen auszufüllen.

0
Nick Robertson

Klasse, die sowohl konkrete als auch nicht konkrete Methoden haben kann, d. H. Mit und ohne Körper.

  1. Methoden ohne Implementierung müssen das Schlüsselwort 'abstract' enthalten.
  2. Abstrakte Klasse kann nicht instanziiert werden.
0
user1639837

Eine abstrakte Klasse ist eine als abstrakt deklarierte Klasse - sie kann abstrakte Methoden enthalten oder nicht. Abstrakte Klassen können nicht instanziiert werden, sie können jedoch Unterklassen enthalten.

Mit anderen Worten, eine Klasse, die mit einem abstrakten Schlüsselwort deklariert wird, 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, sie können zum Erstellen von Objektreferenzen verwendet werden, da der Ansatz von Javas 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();  
    }  
} 
0
Ketan G

Es wird nichts unternommen, es wird lediglich eine allgemeine Vorlage bereitgestellt, die für die Unterklasse freigegeben wird

0
bitfishxyz