Help with inheritence and properties

J

Jack Addington

I have a base form and a base logic class. Each has to know of the other.
I'm then inheriting to create descendant form and descendant logic which
extend both objects and again have to know of each other. I'm getting mixed
up in the syntax/technique on how to refer to the references generically in
the code. I want to be able to always call LogicClass.SomeMethod() and each
FormClass knows what to do with it. In some cases I have 3-4 levels deep.

I can't rationalize what exactly is happening or if its correct, even if
certain ways seem to work. I'm looking for a consistent manner since I seem
to code like this all over the place. Sometimes I seem to get mixed up with
trying to cast up or down... I'm getting quite confused.

1) Is this a waste of resources or does the base class variables not even
get created? I'm assuming then that if I always access throught the Logic
property in all the methods throughout both baseForm and childForm it will
always refer to the coresponding _logic (in the case of childForm the
BaseLogic _logic is never created???)

Class BaseForm{
protected BaseLogic _logic = new BaseLogic( );
public BaseLogic Logic { get{ return _logic;}}

class ChildForm : BaseForm{
protected new ChildLogic _logic = new ChildLogic( );
public new ChildLogic Logic { get{ return _logic;}}
}

Is it bad practice to instantiate the _logic in each inherited object? If I
don't I get stuck in ChildForm where I can't do a (ChildLogic)_logic type
operation...

2) With the example above when I call the following method that isn't
overriden in ChildForm what really happens?

Class BaseForm{
...
public void TestMethod(){
Logic.SomeMethod()
}

SomeOtherClass {
childForm = new ChildForm();
childForm.TestMethod()
}

which _logic does this use? It seems to me that it uses the
ChildForm._logic and as long as the ChildForm._logic has a SomeMethod

I've also tried other ways where I have a method to instatiate the logic
object and then I override the instatiate method in the descendent class.
That assures that I only create the deepest level descended logic objects.

Kinda long winded but I really could use some help..

thx

jack
 
R

Richard Blewett [DevelopMentor]

Try something like this:

class BaseForm
{
protected BaseLogic logic;
public BaseForm()
{
logic = CreateLogic();
}
protected virtual BaseLogic CreateLogic()
{
return new BaseLogic();
}
}

class ChildForm : BaseForm
{
protected override BaseLogic CreateLogic()
{
return new ChildLogic();
}
}

now your code should work.

The problem before is that from the base class your logic member refers to the base version of the logic and so its version of the function gets called. If it referred to the child version (which is what my code above will achieve) you will get the derived version called.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

I have a base form and a base logic class. Each has to know of the other.
I'm then inheriting to create descendant form and descendant logic which
extend both objects and again have to know of each other. I'm getting mixed
up in the syntax/technique on how to refer to the references generically in
the code. I want to be able to always call LogicClass.SomeMethod() and each
FormClass knows what to do with it. In some cases I have 3-4 levels deep.
 
J

Jack Addington

Richard,

Thanks so much. I assuming that this is all independent of adding a
property to do a GetLogic? All though now I don't need to duplicate the
property all the way up the chart.

Now do I need to cast it to (ChildLogic)logic everytime I want to use it in
the ChildForm? or can I use a property to do the cast???
 
R

Richard Blewett [DevelopMentor]

Heres a different implementation that doesn't require calling virtual members from base class constructors (something to generally be avoided because the derived class constructor body hasn't yet run when it's method gets called)

class BaseForm
{
protected BaseLogic logic;
public BaseForm()
{
logic = new BaseLogic();
}
protected BaseForm( BaseLogic logic)
{
this.logic = logic;
}
}

class ChildForm : BaseForm
{
public ChildForm()
: base( new ChildLogic ) // or this(new ChildLogic() )
{
}
protected ChildForm( BaseLogic logic )
: base(logic)
{
}
}

Whether you need each level to have its own property to return the Logic depends on whether the derived Logic classes simply override functionality declared in BaseLogic or whether they add new methods, prooperties, etc. If the former then you can have one property in BaseForm that returns the BaseLogic and no casting is necessary as the overridden versions of functions will get called in place of the base ones. If new methods are being added then it is probably best for the derived versions to have their own property which hides the base version, returning a derived reference to the Logic

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog


Richard,

Thanks so much. I assuming that this is all independent of adding a
property to do a GetLogic? All though now I don't need to duplicate the
property all the way up the chart.

Now do I need to cast it to (ChildLogic)logic everytime I want to use it in
the ChildForm? or can I use a property to do the cast???
 
J

Jack Addington

Beautiful. Thanks. Most of my cases tend to be the later where I add new
methods to the children so I will add new properties where applicable. I
will also use your first implementation (which I had done somewhat by
accident in one spot) to instatiate objects I don't need instatiated in the
constructor.

thanks again

jack
 
J

Jack Addington

One other question:

Why have one public constructor and make the rest protected?
 
J

Jack Addington

another question:

Does calling :base(xxx) call the immediate ancestor or the original
ancestor? ie) if I have inherited 3 times is base always this -1?

thanks
 
R

Richard Blewett [DevelopMentor]

Always the immediate base class

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

another question:

Does calling :base(xxx) call the immediate ancestor or the original
ancestor? ie) if I have inherited 3 times is base always this -1?

thanks
 
R

Richard Blewett [DevelopMentor]

The idea is the only public constructors (for general use by other code) are parameterless. The protected ones are for the derived class to hand down the real BaseLogic derived object. Of course you could have other public ones, but the code was simply to demonstrate how the derived classes can determine the actual Logic type that the base stores. The point is you probably don;t want a client of the form to determine the Logic type (or thats not the impression I got from your original post).

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

One other question:

Why have one public constructor and make the rest protected?
 
B

Bob Grommes

If you call base() from an instance method, it calls whatever implementation
is in place. For example if A is inherited by B, B by C, and C by D, and
you have an implementation in A, but not in B, C or D, and D calls base(),
it will get the A implementation (because that's the implementation used by
C). If you later add an implementation in B, then D will get the B
implementation when it calls base().

Constructors are different; they don't implement inheritance. In that case,
effectively base always calls, as you put it, this minus one. However, if
all your constructors with the same signature in each class call base(), the
net result is the same as it is with instance methods.

--Bob
 

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