[java] Kann eine abstrakte Klasse einen Konstruktor haben?



Answers

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 abstrakten Klasse) durchführen, bevor die Instanziierung einer Unterklasse tatsächlich stattfindet
  • Sie haben letzte Felder in der abstrakten Klasse definiert, aber Sie haben sie nicht in der Deklaration selbst initialisiert. In diesem Fall MÜSSEN Sie einen Konstruktor haben, um diese Felder zu initialisieren

Beachten Sie, dass:

  • Sie können mehr als einen Konstruktor definieren (mit verschiedenen Argumenten)
  • Sie können (sollten?) alle Ihre Konstruktoren als geschützt definieren (sie öffentlich zu machen, ist sowieso sinnlos)
  • Ihr Unterklassenkonstruktor kann einen Konstruktor der abstrakten Klasse aufrufen; es muss es vielleicht sogar aufrufen (wenn es in der abstrakten Klasse keinen no-arg-Konstruktor gibt)

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

Question

Kann eine abstrakte Klasse einen Konstruktor haben?

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




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




Ja, es können abstrakte Klassenkonstruktoren im Allgemeinen für Superaufrufe für Initialisierungsereignisse verwendet werden, die allen Unterklassen gemeinsam sind




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

Es ist ein Kompilierungsfehler, wenn versucht wird, eine Instanz einer abstrakten Klasse unter Verwendung eines Klassenexemplar-Erstellungsausdrucks zu erstellen .

Eine Unterklasse einer abstrakten Klasse, die selbst nicht abstrakt ist, kann instanziiert werden, was zur Ausführung eines Konstruktors für die abstrakte Klasse und somit zur Ausführung der Feldinitialisierer für Instanzvariablen dieser Klasse führt.




In einer konkreten Klasse macht die Deklaration eines Konstruktors für einen konkreten Typ Fnord effektiv zwei Dinge sichtbar:

  • Ein Mittel, mit dem Code die Erstellung einer Instanz von Fnord anfordern kann

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

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




Wie here von javafuns 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
   }
}



Ja ! Abstrakte Klassen können Konstruktoren haben !

Ja, wenn wir eine Klasse als abstrakte Klasse definieren, kann sie nicht instanziiert werden, aber das bedeutet 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 in der entsprechenden Vererbungsstruktur von oben nach unten aufgerufen. Derselbe Fall gilt für abstrakte Klassen. Obwohl wir kein Objekt der abstrakten Klasse erzeugen können, wird beim Konstruieren eines Objekts einer Klasse, die konkret und Unterklasse der abstrakten Klasse ist, automatisch der Konstruktor der abstrakten Klasse aufgerufen. Daher können wir einen Konstruktor in abstrakten Klassen haben.

Hinweis: Eine nicht abstrakte Klasse kann keine abstrakten Methoden haben, aber eine abstrakte Klasse kann eine nicht abstrakte Methode haben. Der Grund ist ähnlich dem von Konstruktoren, Unterschied ist, anstatt automatisch aufgerufen zu werden, können wir super () aufrufen. Es gibt auch nichts wie abstrakter Konstruktor, da es überhaupt keinen Sinn ergibt.




Da eine abstrakte Klasse Variablen aller Zugriffsmodifizierer haben kann, müssen sie auf Standardwerte initialisiert werden, daher ist Konstruktor erforderlich. Wenn Sie die untergeordnete Klasse instanziieren, wird der Konstruktor der abstrakten Klasse aufgerufen und die Variablen werden initialisiert.

Im Gegensatz dazu enthält eine Schnittstelle nur konstante Variablen, dh sie sind bereits initialisiert. So benötigt die Schnittstelle keinen Konstruktor.




Ja, sicher können Sie einen hinzufügen, wie bereits für die Initialisierung von abstrakten Klassenvariablen erwähnt. ABER, wenn Sie nicht explizit eines deklarieren, hat es sowieso einen impliziten Konstruktor für "Constructor Chaining" zu arbeiten.




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 Oberklasse ist abstrakt und hat einen Konstruktor.




Links