Require base class member to be populated by derived classes.

B

Bob Johnson

I have a base class that must have a member variable populated by, and only
by, derived classes.

It appears that if I declare the variable as "internal protected" then the
base class *can* populate the variable, but the population is not *required*
by the derived class (which must be the case).

What would meet the requirements is if I create an abstract method in the
base class that populates the member variable. In this case the derived
classes would be required to implement the method.

Is there another way to meet the requirement?... specifically that a member
variable of a base class *must* be populated by a derived class (and only by
derived classes)?

Thanks!
 
N

Nicholas Paldino [.NET/C# MVP]

Bob,

Internal protected allows internal classes to access the field as well,
so you might want to consider just protected if you want just base classes
to be able to access the field.

There really isn't way to enforce that the derived type populate the
field. The best way I can think of to do this is to set the default value
of the field to a value that is valid for the field type, but not for what
you are trying to do (e.g., 0 if it is an integer, null if it is a reference
type). Then, when your base class works with the field, and it is the
invalid value, you can throw an exception.

Hope this helps.
 
B

Bob Johnson

Yes - it helps. What I'm doing is writing a small console app for purposes
of me learning the strategy pattern. I'm adding reference member variables
to a base class. These reference variables are for adding "behavior" to the
base class (by holding an instance of a class that implements said
behavior). The derived classes then are supposed to implement whatever
behavior is relevant to the derived class BY instantiating and populating
the base class' "behavior variables".

This all works fine and well, but it dawned on me that there is nothing
*requiring* the derived class to implement the behavior (i.e., populate the
base class "behavior bariables".

Thus the question. As the designer of the original implementation here, I'm
thinking that [in a real-world scenario] future developers might add new
derived classes to the system without knowing that they must implement the
behavior (by populating the "behavior variables" in the base class). By
"must implement" I'm thinking that could be a requirement of the real-world
situation... where some class of objects MUST implement some specific
type(s) of behavior (thus they're in the base class) and the particular
behavior is known/added by the derived class at runtime. It would apparently
be up to the documentation (or runtime errors) to inform the future/other
developers that they must implement the behavior.

-Bob



Nicholas Paldino said:
Bob,

Internal protected allows internal classes to access the field as well,
so you might want to consider just protected if you want just base classes
to be able to access the field.

There really isn't way to enforce that the derived type populate the
field. The best way I can think of to do this is to set the default value
of the field to a value that is valid for the field type, but not for what
you are trying to do (e.g., 0 if it is an integer, null if it is a
reference type). Then, when your base class works with the field, and it
is the invalid value, you can throw an exception.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Bob Johnson said:
I have a base class that must have a member variable populated by, and
only by, derived classes.

It appears that if I declare the variable as "internal protected" then
the base class *can* populate the variable, but the population is not
*required* by the derived class (which must be the case).

What would meet the requirements is if I create an abstract method in the
base class that populates the member variable. In this case the derived
classes would be required to implement the method.

Is there another way to meet the requirement?... specifically that a
member variable of a base class *must* be populated by a derived class
(and only by derived classes)?

Thanks!
 
J

james

Abstract is the only way to check this at compile time. You can
guarantee your field is set by putting something like this in the base
class

object m_FieldValue;
object FieldValue
{
get
{
if(m_FieldValue == null)
m_FieldValue = IntialFieldValue;
return m_FieldValue;
}
}
protected abstract object IntialFieldValue { get; }
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Bob Johnson said:
I have a base class that must have a member variable populated by, and only
by, derived classes.

Do you have good reasons for this? , I would love to hear them.

In reality there is no way to enforce this. Of course if you are the one
writting the base class you can be sure of not using it and you are ready :)
another posibility is to use an abstract property. if you do not implement
it in the base class you know for sure it was implemented in a derived class
and you don't really have to worry about members variables.
 
S

Stephen Martin

Make your member variable private to the base class. Then make your base
class constructor protected and have it take a parameter of the variable
type. In order to be instantiated the derived class must call the protected
constructor. Validate the parameter in the constructor and thow an exception
or set your base class variable as the case may be.
 
N

Nicholas Paldino [.NET/C# MVP]

Bob,

I think that in this case, it might be better to provide default
implementations when you expect there to be certain behaviors present, and
then offer a way for the derived class to provide them, if they wish. This
way, if the behaviors aren't provided by the appropriate derived classes,
you have a default to fall back on.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Bob Johnson said:
Yes - it helps. What I'm doing is writing a small console app for purposes
of me learning the strategy pattern. I'm adding reference member variables
to a base class. These reference variables are for adding "behavior" to
the base class (by holding an instance of a class that implements said
behavior). The derived classes then are supposed to implement whatever
behavior is relevant to the derived class BY instantiating and populating
the base class' "behavior variables".

This all works fine and well, but it dawned on me that there is nothing
*requiring* the derived class to implement the behavior (i.e., populate
the base class "behavior bariables".

Thus the question. As the designer of the original implementation here,
I'm thinking that [in a real-world scenario] future developers might add
new derived classes to the system without knowing that they must implement
the behavior (by populating the "behavior variables" in the base class).
By "must implement" I'm thinking that could be a requirement of the
real-world situation... where some class of objects MUST implement some
specific type(s) of behavior (thus they're in the base class) and the
particular behavior is known/added by the derived class at runtime. It
would apparently be up to the documentation (or runtime errors) to inform
the future/other developers that they must implement the behavior.

-Bob



Nicholas Paldino said:
Bob,

Internal protected allows internal classes to access the field as
well, so you might want to consider just protected if you want just base
classes to be able to access the field.

There really isn't way to enforce that the derived type populate the
field. The best way I can think of to do this is to set the default
value of the field to a value that is valid for the field type, but not
for what you are trying to do (e.g., 0 if it is an integer, null if it is
a reference type). Then, when your base class works with the field, and
it is the invalid value, you can throw an exception.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Bob Johnson said:
I have a base class that must have a member variable populated by, and
only by, derived classes.

It appears that if I declare the variable as "internal protected" then
the base class *can* populate the variable, but the population is not
*required* by the derived class (which must be the case).

What would meet the requirements is if I create an abstract method in
the base class that populates the member variable. In this case the
derived classes would be required to implement the method.

Is there another way to meet the requirement?... specifically that a
member variable of a base class *must* be populated by a derived class
(and only by derived classes)?

Thanks!
 
P

Peter Duniho

[...]
What would meet the requirements is if I create an abstract method in the
base class that populates the member variable. In this case the derived
classes would be required to implement the method.

As Nicholas says, there's not a way to force derived classes to initialize
a particular member variable, other than simply stipulating that they must
and doing some sort of run-time check that they have.

Creating an abstract method only requires that a method with the same
signature is implemented in the derived class, but even that does not make
any requirements as to what that method does. It could do nothing, or it
could initialize your member, or it could do something entirely
different. You have no way to control what the implementation actually is.

Pete
 
P

PS

Bob Johnson said:
I have a base class that must have a member variable populated by, and only
by, derived classes.

It appears that if I declare the variable as "internal protected" then the
base class *can* populate the variable, but the population is not
*required* by the derived class (which must be the case).

What would meet the requirements is if I create an abstract method in the
base class that populates the member variable. In this case the derived
classes would be required to implement the method.

Is there another way to meet the requirement?... specifically that a
member variable of a base class *must* be populated by a derived class
(and only by derived classes)?

IPerhaps I am misreading the question. Can't you have an abstract class with
one constructor that has all the "necessary" parameters?

public abstract class Abstract
{
protected int mustSetMe;
public Abstract(int mustSetMe)
{
this.mustSetMe = mustSetMe;
}
}
public class Derived : Abstract
{
public Derived() : base(101)
{
int i = base.mustSetMe;
}
}

PS
 
B

Bob Johnson

YES!

RE:
<< Can't you have an abstract class with one constructor that has all the
"necessary" parameters>>

That gets me what I was looking for. Thanks. So obvious now.

Now please excuse me while I go and knock my head against the wall :)

-B
 
B

Bob Johnson

RE:
<< In reality there is no way to enforce this.>>

What do you think about the suggestion offered by PS - that suggestion was
to populate the base class member variables via constructor parameters???

-B
 
P

Peter Duniho

YES!

RE:
<< Can't you have an abstract class with one constructor that has all the
"necessary" parameters>>

That gets me what I was looking for. Thanks. So obvious now.

But even in that case, the compiler does not impose a mandate that those
parameters be set to anything sensible. You will still need to write the
code to check that.

I think the solution is a nice one, as it ensures that you get to check
during the object's construction that it's properly initialized. But it's
not very different from any of the other half-way solutions that had
already been suggested (nor was it clear from your post that your
requirement was that the "population" happen during construction).

In all cases, the general idea is: have some code in the derived class
that initializes the members, and have some code in the base class that
verifies that initialization. The nice thing about the constructor-based
solution is that the initialization that the derived class does is
required to be _something_ and that the base class gets a chance to look
at the values as they are initialized to check them for validity. But
there's still not any compiler-based requirement that the derived class
initialize them to something sensible, no matter how you do it (which is
what I thought you were looking for, though apparently I misinterpreted
your request).

Pete
 
M

Mark Wilden

I have a base class that must have a member variable populated by, and only
by, derived classes.

Use an abstract property instead of a member variable.

///ark
 
B

Bob Johnson

Thanks for the feedback...

RE:
<<... the compiler does not impose a mandate that those parameters be set
to anything sensible>>

Agreed, but one could also argue that the data types of the parameters,
provided they are something more specific than [object], will necessitate
that the variables are initialized to something that plausibly makes sense
to the base class.

Of course compilers aren't intended to guarantee that we are ever doing
anything sensible (as an objective, by itself, of the compiler)....

RE:
<< nor was it clear from your post that your requirement was that the
"population" happen during construction>>

That wasn't and isn't a requirement. The requirement is that we *somehow*
require the derived class to populate the variable. In retrospect, however,
it makes sense to require that population to happen at construction...
because if not then, then when? Compilers tell us that we can't extend a
sealed class. They tell us that we must implement abstract members. But they
don't tell us that a derived class must populate a member variable of a base
class. It appears that the best?/simplest? thing we can do is have the base
class do this via the constructor.

RE:
<< though apparently I misinterpreted your request>>

The concern for me is that someday another/future developer might want to
extend the base class. And the base class gets some of its functionality
via composition. So it could be quite problemmatic to instantiate the base
class without also setting references to contained class instances. Without
requiring population, then there is lots of room for a future developer to
extend the base class without populating all of the requisite contained
class instances. Thus the OP about how to require a derived class to
populate a member variable of a base class.

In retrospect, the question is better phrased as - how do we initialize a
base class with a specific state. The answer is then totally obvious, as
that's what constructors are for. So we just create a constructor that
requires callers (derived classes in this case) to pass in variables of a
specific type, then the constructor populates the member variable. So
simple.

-B
 
P

Peter Duniho

Agreed, but one could also argue that the data types of the parameters,
provided they are something more specific than [object], will necessitate
that the variables are initialized to something that plausibly makes
sense
to the base class.

Yes, I agree that you at least gain that benefit. As long as you keep in
mind that for value types, you still need to check the value if it
matters, and for reference types at a minimum you need to check that the
reference is non-null (I'm assuming it needs to be, since that seems
implicit in the requirement to "populate" the members).
Of course compilers aren't intended to guarantee that we are ever doing
anything sensible (as an objective, by itself, of the compiler)....

I can't agree 100% with that. I agree that there's a broad class of
things that a compiler has no way to check. But a compiler can and does
check a wide variety of things that impose at least some "is this
sensible?" analysis to things.
[...] But they
don't tell us that a derived class must populate a member variable of a
base
class. It appears that the best?/simplest? thing we can do is have the
base
class do this via the constructor.

You can certainly come close to that. But you cannot meet that goal
entirely at compile time. That's all I'm saying.
The concern for me is that someday another/future developer might want to
extend the base class. And the base class gets some of its functionality
via composition. So it could be quite problemmatic to instantiate the
base
class without also setting references to contained class instances.

I'm not really clear on what the problem would be to have the base class
initialize the members. It seems to me that if a derived class doesn't
want to change the functionality implemented via that composition, that's
the most convenient as well as robust way to do it. And if the derived
class _does_ want to override the base class's behavior, as long as you
have a mechanism for replacing the base-class-initialized members, then
that provides for that with any _requirement_ that the derived class does
so.
[...]
In retrospect, the question is better phrased as - how do we initialize a
base class with a specific state.

To me, the obvious answer is that in the base class constructor, you
initialize the base class with a specific state.

If this state then needs to be changed by the derived class, it can then
do so in _its_ constructor. But I still don't comprehend the need to
_require_ the derived class to do so.

Pete
 
B

Bob Johnson

RE:

<< But I still don't comprehend the need to _require_ the derived class to
do so>>

It's more of a theoretical question (the OP was triggered by a learning
exercise as stated elsewhere in the thread).

Anyway, my thinking was/is as follows:

Suppose we have an application that manages cars. We require that all cars
are capable of playing music (perhaps via a Radio).
In our implementation we have an abstract CarBase class that contains a
member variable of type MusicPlayerBase, also an abstract class.

At runtime we must obviously extend CarBase into a particular car type in
order to have any real/non abstract car (e.g., FiatSpyder). In order to
successfully instantiate any derivative of CarBase, we as authors of CarBase
want to require (for whatever reasons) that the author of the FiatSpyder
class, upon its instantiation, to populate the base CarBase reference with a
MusicPlayerBase. That is, we're requiring the authors of "specific car
classes" that (1) every car must have a radio or some other way to play
music, and (2) we don't know or care what that device is, as long as it's an
extension of MusicPlayerBase. Because we live in a time where that music
player could be anything from an AM Radio to AM/FM radio, to 8-track player
to cassette, to CD, to iPod, to MP3, to ???? we don't want to offer a
default implementation. Yes, we could default to null or AM/FM radio or
whatever, but the pointy-haired boss is requiring that we don't offer any
default value/implementation and instead require the derived class author to
specify the particular MusicPlayerBase they want to implement.

The solution I like best is to specify a paramerer of type MusicPlayerBase
in the constructor of CarBase. Then we're off to the races.

You can see this is pretty much a theoretical question - "how do we
accomplish this" - independent of any particular business reason, yet
possibly driven by business reasons.

Thanks for the dialog.

-B
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top