wake-up-neo.com

Kann eine abstrakte Klasse einen Konstruktor haben?

Kann eine abstrakte Klasse einen Konstruktor haben?

Wenn ja, wie kann es verwendet werden und für welche Zwecke?

529
Szere Dyeri

Ja, eine abstrakte Klasse kann einen Konstruktor haben. Bedenken Sie:

abstract class Product { 
    int multiplyBy;
    public Product( int multiplyBy ) {
        this.multiplyBy = multiplyBy;
    }

    public int mutiply(int val) {
       return multiplyBy * val;
    }
}

class TimesTwo extends Product {
    public TimesTwo() {
        super(2);
    }
}

class TimesWhat extends Product {
    public TimesWhat(int what) {
        super(what);
    }
}

Die Oberklasse Product ist abstrakt und hat einen Konstruktor. Die konkrete Klasse TimesTwo hat einen Konstruktor, der nur den Wert 2 fest codiert. Die konkrete Klasse TimesWhat hat einen Konstruktor, mit dem der Aufrufer den Wert angeben kann.

Abstrakte Konstruktoren werden häufig verwendet, um Klasseneinschränkungen oder Invarianten zu erzwingen, beispielsweise die Mindestfelder, die zum Einrichten der Klasse erforderlich sind.

HINWEIS: Da es keinen Standardkonstruktor (oder keinen Argumenten) im übergeordneten Element gibt Bei der abstrakten Klasse muss der Konstruktor, der in der Unterklasse verwendet wird, explizit den Aufruf von der übergeordnete Konstruktor.

573

Sie würden einen Konstruktor in einer abstrakten Klasse definieren, wenn Sie sich in einer der folgenden Situationen befinden:

  • sie möchten eine -Initialisierung (in Felder der abstract-Klasse) durchführen, bevor die Instanziierung einer Unterklasse tatsächlich stattfindet
  • sie haben letzte Felder in der abstrakten Klasse .__ definiert. Sie haben sie jedoch nicht in der Deklaration selbst initialisiert. In diesem Fall MÜSSEN Sie über einen Konstruktor verfügen, um diese .__-Felder zu initialisieren

Beachten Sie, dass:

  • sie können mehr als einen Konstruktor definieren (mit unterschiedlichen Argumenten).
  • sie können (sollten?) alle Ihre Konstruktoren definieren, die geschützt werden (damit public ist sowieso sinnlos)
  • ihre Unterklassenkonstruktoren können einen Konstruktor der abstrakten Klasse es kann sogar müssen nennen (wenn kein no-arg-Konstruktor in der abstrakten Klasse vorhanden ist)

Vergessen Sie auf keinen Fall, dass der Compiler automatisch einen für Sie generiert, wenn Sie keinen Konstruktor definieren (dieser ist öffentlich, hat keine Argumente und tut nichts).

143
jfpoilpret

Ja, es kann einen Konstruktor haben, und es ist definiert und verhält sich wie jeder Konstruktor einer anderen Klasse. Abgesehen davon, dass abstrakte Klassen nicht direkt instanziiert werden können, sondern nur erweitert werden, erfolgt die Verwendung daher immer vom Konstruktor einer Unterklasse.

52
Lawrence Dol

Ja ! Abstrakte Klassen können Konstruktoren haben !

Ja, wenn wir eine Klasse als abstrakte Klasse definieren, kann diese nicht instanziiert werden. Dies bedeutet jedoch nicht, dass eine abstrakte Klasse keinen Konstruktor haben kann. Jede abstrakte Klasse muss eine konkrete Unterklasse haben, die die abstrakten Methoden dieser abstrakten Klasse implementiert.

Wenn wir ein Objekt einer Unterklasse erstellen, werden alle Konstruktoren im entsprechenden Vererbungsbaum im Ansatz von oben nach unten aufgerufen. Der gleiche Fall gilt für abstrakte Klassen. Obwohl wir kein Objekt einer abstrakten Klasse erstellen können, wird der Konstruktor der abstrakten Klasse automatisch aufgerufen, wenn wir ein Objekt einer Klasse erstellen, das konkret ist und eine Unterklasse der abstrakten Klasse ist. Daher können wir einen Konstruktor in abstrakten Klassen haben.

Anmerkung: Eine nicht abstrakte Klasse kann keine abstrakten Methoden haben, aber eine abstrakte Klasse kann eine nicht abstrakte Methode haben. Der Grund ist ähnlich wie bei Konstruktoren, da der Unterschied nicht automatisch aufgerufen wird, sondern super (). Es gibt auch keinen abstrakten Konstruktor, der überhaupt keinen Sinn macht.

33
Aniket Thakur

Das kann es nicht nur, das tut es immer. Wenn Sie keine Klasse angeben, hat sie einen Standardkonstruktor ohne Argon wie jede andere Klasse. Tatsächlich erhalten ALLE Klassen, einschließlich verschachtelter und anonymer Klassen, einen Standardkonstruktor, wenn keiner angegeben ist (bei anonymen Klassen ist es unmöglich, einen zu spezifizieren, daher wird immer der Standardkonstruktor verwendet).

Ein gutes Beispiel für eine abstrakte Klasse mit einem Konstruktor ist die Klasse Calendar . Sie erhalten ein Calendar-Objekt, indem Sie Calendar.getInstance () aufrufen, aber es enthält auch Konstruktoren, die geschützt sind. Der Grund, warum seine Konstruktoren geschützt werden, besteht darin, dass nur ihre Unterklassen sie (oder Klassen in demselben Paket) aufrufen können, da sie jedoch abstrakt sind, gilt dies nicht. GregorianCalendar ist ein Beispiel für eine Klasse, die Calendar erweitert.

13
MattC

Eine abstrakte Klasse kann einen Konstruktor haben. ABER Sie können kein Objekt der abstrakten Klasse erstellen. Wie verwenden Sie diesen Konstruktor?

Wenn Sie diese abstrakte Klasse in Ihrer Unterklasse erben, können Sie Werte an ihren (abstrakten) Konstruktor über die Super (value) -Methode in Ihrer Unterklasse übergeben. 

mit super können Sie also Werte in einem Konstruktor der abstrakten Klasse übergeben. Soweit ich mich erinnere, muss dies die erste Anweisung in Ihrer Methode oder Ihrem Konstruktor sein. 

6
Alok

Ja, abstrakte Konstruktoren für abstrakte Klassen werden im Allgemeinen für übergeordnete Aufrufe von Initialisierungsereignissen verwendet, die für alle Unterklassen gelten

5
Jacob

Obwohl es viele gute Antworten gibt, möchte ich meine 2 Cent geben.

Konstruktor baut das Objekt nicht . Es wird verwendet, um ein Objekt zu initialisieren.

Ja, eine Abstract-Klasse hat immer einen Konstruktor. Wenn Sie keinen eigenen Konstruktor definieren, wird der Compiler der Abstract-Klasse einen Standardkonstruktor zuweisen. Das oben stehende gilt für alle Klassen - verschachtelt, abstrakt, anonym usw. 

Eine abstrakte Klasse (im Gegensatz zur Schnittstelle) kann nicht endgültige nicht statische Felder enthalten, die initialisiert werden müssen. Sie können dazu einen eigenen Konstruktor in der abstrakten Klasse schreiben. In diesem Fall gibt es jedoch keinen Standardkonstruktor.

public abstract class Abs{
    int i;
    int j;
    public Abs(int i,int j){
        this.i = i;
        this.j = j;
        System.out.println(i+" "+j);
    }
}

Seien Sie vorsichtig, wenn Sie über abstrakte Klassen hinausgehen. Sie müssen von jedem Konstruktor explizit Super aufrufen. Die erste Zeile eines Konstruktors ruft super () auf. Wenn Sie super () nicht explizit aufrufen, erledigt Java dies für Sie . Der folgende Code wird nicht kompiliert:

public class Imp extends Abs{

public Imp(int i, int j,int k, int l){
    System.out.println("2 arg");
}
}

Sie müssen es wie im folgenden Beispiel verwenden:

public class Imp extends Abs{

public Imp(int i, int j,int k, int l){
    super(i,j);
    System.out.println("2 arg");
}
}
4
Harshil

Natürlich kann eine abstrakte Klasse einen Konstruktor haben. Allgemein wird der Klassenkonstruktor zum Initialisieren von Feldern verwendet. So wird ein abstrakter Klassenkonstruktor zum Initialisieren der Felder der abstrakten Klasse verwendet. Sie würden einen Konstruktor für eine abstrakte Klasse bereitstellen, wenn Sie bestimmte Felder der abstrakten Klasse initialisieren möchten, bevor die Instanziierung einer untergeordneten Klasse erfolgt. Ein abstrakter Klassenkonstruktor kann auch verwendet werden, um Code auszuführen, der für jede untergeordnete Klasse relevant ist. Dies verhindert die Duplizierung von Code.

Wir können keine Instanz einer abstrakten Klasse erstellen. Wir können jedoch Instanzen von Klassen erstellen, die von der abstrakten Klasse abgeleitet sind. Wenn also eine Instanz einer abgeleiteten Klasse erstellt wird, wird der Konstruktor der übergeordneten abstrakten Klasse automatisch aufgerufen.

Referenz: Dieser Artikel

3
Raj Baral

Bedenken Sie:

abstract class Product { 
    int value;
    public Product( int val ) {
        value= val;
    }
    abstract public int multiply();
}

class TimesTwo extends Product {
    public int mutiply() {
       return value * 2;
    }
}

Die Superklasse ist abstrakt und hat einen Konstruktor.

2
S.Lott

In einer konkreten Klasse enthüllt die Deklaration eines Konstruktors für einen konkreten Typ Fnord zwei Dinge:

  • Eine Methode, mit der Code die Erstellung einer Instanz von Fnord anfordern kann

  • Ein Mittel, mit dem eine Instanz eines von Fnord abgeleiteten Typs , die sich im Aufbau befindet, die Initialisierung aller Basisklassenmerkmale anfordern kann.

Während es vielleicht ein Mittel geben sollte, mit dem diese beiden Fähigkeiten getrennt gesteuert werden können, wird für jeden konkreten Typ eine Definition beides ermöglichen. Obwohl die erste Fähigkeit für eine abstrakte Klasse nicht von Bedeutung ist, ist die zweite Fähigkeit für eine abstrakte Klasse genauso bedeutsam wie für jede andere Klasse, und daher ist ihre Deklaration ebenso notwendig und nützlich.

2
supercat

ja, so ist es. Ein Konstruktor einer abstrakten Klasse wird aufgerufen, wenn eine Instanz einer geerbten Klasse erstellt wird. Das Folgende ist beispielsweise ein gültiges Java-Programm.

// An abstract class with constructor
abstract class Base {
Base() { System.out.println("Base Constructor Called"); }
abstract void fun();
    }
class Derived extends Base {
Derived() { System.out.println("Derived Constructor Called"); }
void fun() { System.out.println("Derived fun() called"); }
    }

class Main {
public static void main(String args[]) { 
   Derived d = new Derived();
    }

}

Dies ist die Ausgabe des obigen Codes.

Basiskonstruktor aufgerufen Abgeleiteter Konstruktor aufgerufen

referenzen: Linkbeschreibung hier eingeben

2
chamzz.dot

Um eine Konstruktorverkettung zu erreichen, verfügt die abstrakte Klasse über einen Konstruktor ..__ Der Compiler behält die Super () - Anweisung im Unterklassenkonstruktor, der den Superklassenkonstruktor aufrufen wird. Wenn es keine Konstruktoren für abstrakte Klassen gab, werden gegen Java-Regeln verstoßen, und wir können keine Verkettung von Konstruktoren erreichen.

1
Anilkumar K S

Ja, abstrakte Klassen können Konstruktoren haben!  

Hier ist ein Beispiel, das den Konstruktor in der abstrakten Klasse verwendet:

abstract class Figure { 

    double dim1;        
    double dim2; 

    Figure(double a, double b) {         
        dim1 = a;         
        dim2 = b;         
    }

    // area is now an abstract method 

   abstract double area(); 

}


class Rectangle extends Figure { 
    Rectangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for rectangle 
    double area() { 
        System.out.println("Inside Area for Rectangle."); 
        return dim1 * dim2; 
    } 
}

class Triangle extends Figure { 
    Triangle(double a, double b) { 
        super(a, b); 
    } 
    // override area for right triangle 
    double area() { 
        System.out.println("Inside Area for Triangle."); 
        return dim1 * dim2 / 2; 
    } 
}

class AbstractAreas { 
    public static void main(String args[]) { 
        // Figure f = new Figure(10, 10); // illegal now 
        Rectangle r = new Rectangle(9, 5); 
        Triangle t = new Triangle(10, 8); 
        Figure figref; // this is OK, no object is created 
        figref = r; 
        System.out.println("Area is " + figref.area()); 
        figref = t; 
        System.out.println("Area is " + figref.area()); 
    } 
}

Ich glaube, du hast die Antwort bekommen.

1
Ketan G

Ja, eine abstrakte Klasse kann einen Konstruktor haben. Sie können in einer abstrakten Klasse beliebig viele Konstruktoren überladen. Diese Kontrahenten können verwendet werden, um den Anfangszustand der Objekte, die die abstrakte Klasse erweitern, zu initialisieren. Wie wir wissen, können wir aus einer abstrakten Klasse kein Objekt erstellen, da Objekte von den "neuen" Schlüsselwörtern und nicht von den Konstruktoren erstellt werden. Sie dienen nur dazu, den Zustand der Unterklassenobjekte zu initialisieren.

1
Shubham Soni

Eine abstrakte Klasse kann einen Konstruktor haben, der jedoch nicht instanziiert werden kann. Der in einer abstrakten Klasse definierte Konstruktor kann jedoch zur Instantiierung der konkreten Klasse dieser abstrakten Klasse verwendet werden. Überprüfen Sie JLS :

Es ist ein Fehler bei der Kompilierung, wenn versucht wird, eine Instanz einer abstrakten Klasse mithilfe einer Klasseninstanzerstellung zu erstellen Ausdruck.

Eine Unterklasse einer abstrakten Klasse, die selbst nicht abstrakt ist, kann .__ sein. instanziiert, was zur Ausführung eines Konstruktors für die .__ führt. abstrakte Klasse und daher die Ausführung der Feldinitialisierer zum Beispiel Variablen dieser Klasse.

1
i_am_zero

Wie von javafuns hier beschrieben, ist dies ein Beispiel:

public abstract class TestEngine
{
   private String engineId;
   private String engineName;

   public TestEngine(String engineId , String engineName)
   {
     this.engineId = engineId;
     this.engineName = engineName;
   }
   //public gettors and settors
   public abstract void scheduleTest();
}


public class JavaTestEngine extends TestEngine
{

   private String typeName;

   public JavaTestEngine(String engineId , String engineName , String typeName)
   {
      super(engineId , engineName);
      this.typeName = typeName;
   }

   public void scheduleTest()
   {
     //do Stuff
   }
}
1
jaideep

Da eine abstract-Klasse über Variablen aller Zugriffsmodifizierer verfügen kann, müssen sie mit Standardwerten initialisiert werden, sodass ein Konstruktor erforderlich ist. Wenn Sie die untergeordnete Klasse instanziieren, werden ein Konstruktor einer abstrakten Klasse und Variablen aufgerufen werden initialisiert.

Im Gegensatz dazu enthält ein interface nur konstante Variablen, dh sie sind bereits initialisiert. Die Schnittstelle benötigt also keinen Konstruktor.

1
Arun Raaj

Der Zweck des Konstruktors in einer Klasse dient dazu, Felder zu initialisieren , aber nicht "Objekte zu erstellen". Wenn Sie versuchen, eine neue Instanz einer abstrakten SuperClass zu erstellen, gibt der Compiler einen Fehler aus. Wir können jedoch eine abstrakte Klasse Employee erben und ihren Konstruktor verwenden, indem Sie ihre Variablen festlegen. Siehe Beispiel unten

public abstract class Employee {
  private String EmpName;
  abstract double calcSalary();

  Employee(String name) {
    this.EmpName = name;// constructor of abstract class super class
  }
}

class Manager extends Employee{
 Manager(String name) {
    super(name);// setting the name in the constructor of sub class
 }
double calcSalary() {
    return 0;
 }
}
0
karto

Ja, Sie können sicherlich eine hinzufügen, wie bereits für die Initialisierung von Abstract-Klassenvariablen erwähnt. Wenn Sie jedoch keine explizit deklarieren, hat dies einen impliziten Konstruktor für "Constructor Chaining". 

0
Kedar Parikh