739 Stimmen

Kann eine abstrakte Klasse einen Konstruktor haben?

Kann eine abstrakte Klasse einen Konstruktor haben?

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

749voto

Michael Rutherfurd Punkte 13367

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

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 einfach den Wert 2 fest einträgt. Die konkrete Klasse TimesWhat hat einen Konstruktor, der es dem Aufrufer ermöglicht, den Wert anzugeben.

Abstrakte Konstruktoren werden häufig verwendet, um Klasseneinschränkungen oder Invarianten durchzusetzen, wie z. B. die Mindestanzahl von Feldern, die zur Einrichtung der Klasse erforderlich sind.

HINWEIS: Da es in der übergeordneten abstrakten Klasse keinen Standardkonstruktor (oder Konstruktor ohne Argument) gibt abstrakten Klasse gibt, muss der in der Unterklasse verwendete Konstruktor explizit den den übergeordneten Konstruktor aufrufen.

84 Stimmen

@Jonathon: Es bringt keinen wirklichen Nutzen, wenn man die Komplexität zum Zwecke der Beantwortung der gestellten Frage erhöht. Wenn sich die Frage auf den Anwendungsbereich bezöge, dann wäre es in der Tat sinnvoll, die drei nützlichen Möglichkeiten gegenüberzustellen.

38 Stimmen

Ich glaube, Jonathon wollte nur sagen, dass ein öffentlicher Konstruktor für eine abstrakte Klasse keinen Sinn macht, weil man eine abstrakte Klasse nicht direkt instanziieren kann (man kann sie nur über einen abgeleiteten Typ instanziieren, der selbst nicht als abstrakt gekennzeichnet ist).

7 Stimmen

Der Konstruktor in "TimesTwo" ist kein Standardkonstruktor.

186voto

jfpoilpret Punkte 10291

In einer solchen Situation würden Sie einen Konstruktor in einer abstrakten Klasse definieren:

  • Sie möchten einige Initialisierung (für Felder der abstrakten Klasse) vor der Instanziierung einer Unterklasse tatsächlich stattfindet
  • haben Sie die endgültigen Felder in der Datei abstrakten Klasse definiert, aber Sie haben sie nicht sie nicht in der Deklaration initialisiert selbst initialisiert; in diesem Fall MÜSSEN Sie einen einen Konstruktor zur Initialisierung dieser Felder zu initialisieren

Beachten Sie das:

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

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

1 Stimmen

Ein Bonus für den Schutz der Kinder. Es fügt das nette Bit der Vollständigkeit.

75voto

Lawrence Dol Punkte 61053

Ja, sie kann einen Konstruktor haben, der definiert ist und sich genauso verhält wie der Konstruktor jeder anderen Klasse. Abgesehen davon, dass abstrakte Klassen nicht direkt instanziiert, sondern nur erweitert werden können, erfolgt die Verwendung also immer über den Konstruktor einer Unterklasse.

60voto

Aniket Thakur Punkte 62911

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 beliebigen Unterklasse erstellen, werden alle Konstruktoren im entsprechenden Vererbungsbaum von oben nach unten aufgerufen. Das Gleiche gilt für abstrakte Klassen. Wir können zwar kein Objekt einer abstrakten Klasse erzeugen, aber wenn wir ein Objekt einer Klasse erzeugen, die konkret und Unterklasse der abstrakten Klasse ist, wird 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 dafür ist ähnlich wie bei den Konstruktoren, mit dem Unterschied, dass wir super() aufrufen können, anstatt automatisch aufgerufen zu werden. Außerdem gibt es keinen abstrakten Konstruktor, da er überhaupt keinen Sinn macht.

16 Stimmen

Anmerkung zum Spruch ... der Konstruktor der abstrakten Klasse wird automatisch aufgerufen ... dass dies nur auf den Standardkonstruktor der abstrakten Klasse zutrifft, andere müssten explizit über super(args) aufgerufen werden.

2 Stimmen

Nicht-Standard-Konstruktoren können automatisch aufgerufen werden, sofern es sich um Konstruktoren ohne Argumente handelt. Es gilt also nicht nur für Standardkonstruktoren.

16voto

MattC Punkte 5409

Er kann es nicht nur, er tut es immer. Wenn Sie keinen Konstruktor angeben, hat sie einen Standardkonstruktor ohne Argumente, genau wie jede andere Klasse. Tatsächlich erhalten ALLE Klassen, einschließlich verschachtelter und anonymer Klassen, einen Standardkonstruktor, wenn keiner angegeben wird (im Falle anonymer Klassen ist es unmöglich, einen anzugeben, daher erhalten Sie immer den Standardkonstruktor).

Ein gutes Beispiel für eine abstrakte Klasse, die einen Konstruktor hat, ist die Kalender Klasse. Sie erhalten ein Calendar-Objekt, indem Sie Calendar.getInstance() aufrufen, aber es hat auch Konstruktoren, die geschützt sind. Der Grund dafür, dass die Konstruktoren geschützt sind, ist, dass nur ihre Unterklassen sie aufrufen können (oder Klassen im selben Paket, aber da es sich um eine abstrakte Klasse handelt, trifft das nicht zu). GregorianCalendar ist ein Beispiel für eine Klasse, die Calendar erweitert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X