Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

providing abstract class member variables from a subclass

What is the 'correct' way of providing a value in an abstract class from a concrete subclass?

ie, should I do this:

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") {}
}

or this:

abstract class A {

    protected A() { }

    public abstract string Value { get; }
}

class B : A {
    B() {}

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

or something else?

And should different things be done if the Value property is only used in the abstract class?

like image 806
thecoop Avatar asked Nov 04 '09 16:11

thecoop


1 Answers

I usually prefer the first approach because it requires less code in child classes.

However, I admit that the semantics of the second approach are clearer in a subtle way. Overriding the property says "this property's implementation is part of my identity." Passing a constructor argument has a different connotation: "I'm setting a value in this other thing, which just happens to be my base class." It implies composition (has-a) rather than inheritance (is-a).

And should different things be done if the Value property is only used in the abstract class?

In this case, you should definitely use the first (constructor-oriented) approach so you can hide that implementation detail from subclasses.

Likewise if you need to use the value in the constructor; as Marc mentioned this is an actual technical reason to use the first approach. Though it wouldn't matter in this specific scenario, if someone later modifies the property override to use some other member variable in the derived class, you might have a subtle bug on your hands.

like image 193
Jeff Sternal Avatar answered Sep 29 '22 03:09

Jeff Sternal