Frage

Warum kann Java-Klassen haben abstrakte Felder, wie sie abstrakte Methoden haben können?

Zum Beispiel: Ich habe zwei Klassen, die die gleiche abstrakte Basisklasse erweitern. Diese beiden Klassen haben jeweils ein Verfahren, das mit Ausnahme einer Zeichenkette identisch ist, die eine Fehlermeldung passiert werden, in ihnen. Wenn Felder abstrakt sein könnten, könnte ich diese Konstante abstrakt machen und das Verfahren bis in die Basisklasse ziehen. Stattdessen muss ich eine abstrakte Methode erstellen, getErrMsg() in diesem Fall genannt, dass die Zeichenfolge zurückgibt, überschreiben diese Methode in den beiden abgeleiteten Klassen, und dann kann ich die Methode nach oben ziehen (die nun ruft die abstrakte Methode).

Warum kann ich nicht machen nur das Feld mit abstraktem zu beginnen? Könnte Java wurden entwickelt, um dies zu ermöglichen?

War es hilfreich?

Lösung

Sie können tun, was Sie beschrieben durch ein letztes Feld in der abstrakten Klasse hat, die in seinem Konstruktor (ungetestet Code) initialisiert:

abstract class Base {

    final String errMsg;

    Base(String msg) {
        errMsg = msg;
    }

    abstract String doSomething();
}

class Sub extends Base {

    Sub() {
        super("Sub message");
    }

    String doSomething() {

        return errMsg + " from something";
    }
}

Wenn Ihr Kind Klasse „vergisst“, um die letzte durch den Super-Konstruktor initialisiert der Compiler geben eine Warnung einen Fehler, wie wenn eine abstrakte Methode nicht implementiert ist.

Andere Tipps

Ich sehe keinen Sinn darin. Sie können die Funktion der abstrakten Klasse bewegen und nur einige Schutzfeld außer Kraft setzen. Ich weiß nicht, ob dies mit Konstanten funktioniert, aber die Wirkung ist das gleiche:

public abstract class Abstract {
    protected String errorMsg = "";

    public String getErrMsg() {
        return this.errorMsg;
    }
}

public class Foo extends Abstract {
    public Foo() {
       this.errorMsg = "Foo";
    }

}

public class Bar extends Abstract {
    public Bar() {
       this.errorMsg = "Bar";
    }
}

Also Ihr Punkt ist, dass Sie die Implementierung / überwiegenden / was auch immer von errorMsg in den Unterklassen erzwingen mögen? Ich dachte, Sie nur die Methode in der Basisklasse haben wollte und wusste nicht, wie man mit dem Gebiet befassen dann.

Natürlich ist es könnte ist entworfen worden, um dies zu ermöglichen, aber unter der Decke würde es nach wie vor dynamische Dispatch zu tun hat, und damit ein Methodenaufruf. Java-Design (zumindest in den frühen Tagen) war bis zu einem gewissen Grad, ein Versuch, minimalistisch zu sein. Das heißt, versuchten die Designer das Hinzufügen neuer Funktionen zu vermeiden, wenn sie leicht durch andere Funktionen, die bereits in der Sprache simuliert werden können.

Lesen Sie Ihren Titel, ich dachte, du abstrakte Instanz Mitglieder bezogen sich; und ich konnte nicht viel Verwendung für sie sehen. Aber abstrakte statische Mitglieder ist eine ganz andere Sache.

Ich habe oft gewünscht, dass ich eine Methode, wie die folgenden in Java erklären könnte:

public abstract class MyClass {

    public static abstract MyClass createInstance();

    // more stuff...

}

Im Grunde würde Ich mag darauf bestehen, dass konkrete Implementierungen meiner Eltern-Klasse eine statische Factory-Methode mit einer bestimmten Signatur bereitzustellen. Dies würde erlauben Sie mir einen Hinweis auf eine konkrete Klasse mit Class.forName() zu bekommen und sicher sein, dass ich eine in einer Konvention meiner Wahl konstruieren könnte.

Eine weitere Option ist das Feld als öffentlich (endgültig, wenn Sie möchten) zu definieren, die in der Basisklasse und initialisieren dann das Feld in dem Konstruktor der Basisklasse, abhängig davon, welche Unterklasse derzeit verwendet wird. Es ist ein bisschen schattig, dass sie eine kreisförmige Abhängigkeit führt. Aber zumindest ist es nicht eine Abhängigkeit, die jemals ändern kann - d. H wird die Unterklasse entweder vorhanden oder nicht vorhanden ist, aber die Unterklasse Methoden oder Felder können nicht den Wert von field beeinflussen

public abstract class Base {
  public final int field;
  public Base() {
    if (this instanceof SubClassOne) {
      field = 1;
    } else if (this instanceof SubClassTwo) {
      field = 2;
    } else {
      // assertion, thrown exception, set to -1, whatever you want to do 
      // to trigger an error
      field = -1;
    }
  }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top