Charles
Charles

Reputation: 548

C# base inheritance

This issue has been on/off bugging me and I've written 4 wrappers now. I'm certain I'm doing it wrong and need to figure out where my understanding is branching off.

Let's say I'm using the Rectangle class to represent bars of metal. (this works better then animals)

So say the base class is called "Bar".

private class Bar
{
   internal Rectangle Area;
}

So. Now we make a rectangle, say 300 units by 10 units.

private Bar CreateBar()
{
    Bar1 = new Bar1();
    Bar1.Area = new Rectangle(new Point(0,0), new Size(300,10));
    return Bar1;
}

Fantastic, so we have a base bar.

Now let's say we want to make this bar have a material - say steel. So. . .

private class SteelBar : Bar
{
    string Material;
}

So if I did this. . .

private SteelBar CreateSteelBar()
{
    SteelBar SteelB = new SteelB();
    Bar B = CreateBar();
    SteelB = B;
    SteelB.Material = "Steel";
    return SteelB;
}

From what I get from this if I call CreateSteelBar, it creates a steelbar that calls CreateBar. So I end up with a steel bar with a 300 by 10 rectangle, and a nulled or empty string for material. Then I set the material to steel.

When I try something similar in my program, it keeps telling I cannot implicitly create a higher up class from a lower down class. I would have figured this is why inheritance exists considering all the inherits from animal examples I see, but am hoping someone can clear me up.

Also, I'm certain I could call SteelBar = CreateBar(); but I did it the long way here.

Upvotes: 5

Views: 375

Answers (8)

John Culviner
John Culviner

Reputation: 22944

Consider this example:

public class Super {
}

public class Sub : Super {
}

If you create object Super you cannot assign it to be a Sub because it is not a "Sub". OO programming allows you to "deal with" objects in terms of less derived classes but this simple fact still remains:

You have created a Super not a Sub.

The only way to create a Sub from a Super would be to create a new Sub and copy property values. A tool like AutoMapper works well to do this quickly otherwise you will end up with a bunch of lines of mundane brittle code.

Upvotes: 0

m.edmondson
m.edmondson

Reputation: 30862

I'm pretty sure your problem is you're trying to upcast:

Bar B = CreateBar();
SteelBar = B;

This isn't right because even though SteelBar MUST be of type Bar (because it inherited from) the same cannot be done backwards.

The opposite would be legal:

SteelBar B = CreateBar();
Bar = (Bar)B;

Quite simply you are attempting to store a reference of SteelBar in Bar, whereas it could possibly be another bar type such as WoodenBar.

Upvotes: 0

GETah
GETah

Reputation: 21409

it keeps telling I cannot implicitly create a higher up class from a lower down class

The best example I use for this is Fruit and apple. Inheritance is an "is-a" relationship. An apple is-a Fruit but a Fruit is not an apple as it can be an orange, banana ...

Back to your example, a SteelBar is a Bar but a Bar is not a SteelBar as it can be a WoodenBar and that explains why you can not cast the super class to the child class

Upvotes: 1

Jay
Jay

Reputation: 3355

Surely this would be easier to achieve with abstractions such as Interfaces ... e.g. IMeasureable and IPhysical and not Base Classes...

I would use a BaseClass only in the GUI Representation for easy of displaying them and I would force the base class to implement the required interfaces.

You could optionally also use a DisplayObject which is sealed and takes an IMeasurable or IPhysical...

Upvotes: 0

Matthias Meid
Matthias Meid

Reputation: 12503

As pycruft mentioned you cannot assign an object of a basetype to a subtype-variable. I don't understand why you add a SteelBar anyway, as you have a Material property too. This looks redundant to me.

To achieve what you're trying to do, you have to create a new factory method that builds a SteelBar from the very beginning. It may return it as a Bar anyway. This would be an implementation of the Factory Pattern.

However, some more information about what you're trying to achieve might help.

Upvotes: 1

Dour High Arch
Dour High Arch

Reputation: 21711

Here's your problem:

Bar B = CreateBar();
SteelB = B;

B is a bar of any kind. You are trying to assign it to a SteelBar. That's wrong, it could be a bar of any kind (copper, wood, Tiki, ...). You can do this:

SteelBar sb = new SteelBar();
Bar b = sb;

Because a SteelBar is a bar of some kind, but the reverse is not true..

Also, I'm certain I could call SteelBar = CreateBar()

You're certain of something that is false. Try it; CreateBar returns an instance of a bar of any kind, not a SteelBar.

Upvotes: 3

Reed Copsey
Reed Copsey

Reputation: 564333

Instead of having a method (CreateBar), you'd use a constructor:

public Bar()
{
    this.Area = new Rectangle(new Point(0,0), new Size(300,10));
}

Then, in SteelBar, you'd call the base class constructor:

public SteelBar()
{
    this.Material = "Steel";
}

The base class constructor will occur first, so your area will already be setup. You can be explicit about this, though, and show it in your code:

public SteelBar()
    : base()
{
    this.Material = "Steel";
}

However, this is typically only used if you want to have a specific constructor that takes arguments.

For details, see Constructors in the C# programming guide.

Upvotes: 16

pycruft
pycruft

Reputation: 68745

You can't do this :

SteelBar = B;

You've created a new object of type Bar and you're trying to assign it to a reference of type SteelBar.

Upvotes: 0

Related Questions