7 Stimmen

Bereitstellung abstrakter Klassenvariablen aus einer Unterklasse

Was ist der "richtige" Weg, um einen Wert in einer abstrakten Klasse aus einer konkreten Unterklasse bereitzustellen?

d. h., sollte ich dies tun:

abstract class A {
    private string m_Value;

    protected A(string value) {
        m_Value = value;
    }

    public string Value {
        get { return m_Value; }
    }
}

class B : A {
    B() : this("string value") {}
}

oder dies:

abstract class A {

    protected A() { }

    public abstract string Value { get; }
}

class B : A {
    B() {}

    public override string Value {
        get { return "string value"; }
    }
}

oder etwas anderes?

Und sollten andere Dinge getan werden, wenn die Value Eigenschaft nur in der abstrakten Klasse verwendet wird?

2voto

Jeff Sternal Punkte 46528

Ich bevorzuge in der Regel den ersten Ansatz, weil er weniger Code in den untergeordneten Klassen erfordert.

Ich gebe jedoch zu, dass die Semantik des zweiten Ansatzes auf subtile Weise klarer ist. Das Überschreiben der Eigenschaft besagt "die Implementierung dieser Eigenschaft ist Teil von meine Identität". Die Übergabe eines Konstruktorarguments hat eine andere Konnotation: "Ich setze einen Wert in diesem anderen Ding, das zufällig meine Basisklasse ist". Es impliziert Komposition (has-a) und nicht Vererbung (is-a).

Und sollten verschiedene dünne die Eigenschaft Value nur in der abstrakten Klasse verwendet wird?

In diesem Fall sollten Sie auf jeden Fall den ersten (konstruktororientierten) Ansatz verwenden, damit Sie dieses Implementierungsdetail vor Unterklassen verbergen können.

Gleiches gilt, wenn Sie den Wert im Konstruktor verwenden müssen; als Marc erwähnt dies ist ein tatsächlicher technischer Grund für den ersten Ansatz. Obwohl es in diesem speziellen Szenario keine Rolle spielen würde, wenn jemand später die Überschreibung der Eigenschaft ändert, um eine andere Mitgliedsvariable in der abgeleiteten Klasse, haben Sie möglicherweise einen subtilen Fehler in der Hand.

1voto

Marc Gravell Punkte 970173

Es kommt darauf an; muss die Basisklasse im ctor davon wissen? Wenn ja, muss die override Ansatz eine schlechte Idee sein kann ( virtual funktioniert nicht sehr gut innerhalb des ctor). Ansonsten ist beides in Ordnung.

1voto

Mario F Punkte 41039

Ich halte das zweite Idiom für besser, da es überschaubarer ist (wenn Ihre Basisklasse mehrere Eigenschaften benötigt, die in einer abgeleiteten Klasse definiert sind, kann der Konstruktor unübersichtlich werden). Es ist auch klarer, woher die Informationen kommen. Wenn Sie die Value Eigenschaft wissen Sie, dass sie in einer Unterklasse definiert ist. Im ersten Beispiel müssen Sie den Definitionspunkt der Eigenschaft m_Value Variable, die in der Basisklasse geändert werden kann.

1voto

Paolo Tedesco Punkte 52228

Ich denke, es ist so ziemlich dasselbe: Man muss sich für einen Weg entscheiden und diesen aus Gründen der Kohärenz beibehalten.

Beide Lösungen zwingen die abgeleitete Klasse, einen Wert bereitzustellen, was gut ist; eine mögliche Alternative, falls ein Wert nicht erforderlich sein sollte:

abstract class A {
    public string Value {
        get;
        protected set;
    }
}

Ich persönlich bevorzuge die erste Option (Konstruktorparameter), weil ich sie für die klarere halte, aber das ist wirklich Geschmackssache.

1voto

Yogesh Punkte 14098

Das kommt darauf an.

Ich werde den ersten Weg wählen, wenn ich Änderungen vornehmen muss. Value in der abstrakten Klasse.

Ich werde den zweiten Weg nur dann wählen, wenn ich viele Klassen von einer anderen Klasse erben muss. A und irgendwo muss ich die geerbten Klassen mit der abstrakten Basisklasse verbinden.

Wenn beides nicht zutrifft, werde ich den zweiten Ansatz wählen, der handlicher und sauberer ist.

Wenn Value nur in der abstrakten Klasse verwendet wird, deklariere ich sie als private Feld anstelle einer Eigenschaft.

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