Kelsie
Kelsie

Reputation: 1020

Is it bad form to refer to a derived type in a base type?

I have a category/file tree structure. Both categories and files can have parents, so I derived them from a common base class that has a Parent property. Since all parents will obviously always be categories (files can't be a parent), it seems to make sense to make the Parent property of the node be the CategoryNode type.

Is it bad form for the base class to refer to the derived class? If so, why? What's a better way to structure this, if so?

class Node {
    public CategoryNode Parent {get; set;}
}

class File : Node {
    ...
}

class CategoryNode : Node {
    ...
}

Upvotes: 8

Views: 195

Answers (4)

Steve B
Steve B

Reputation: 37700

If the property Parent is actually a common properties of all descendants and always of kind CategoryNode, it's not a problem. Semantically speaking it's correct and technically I think its correct too as soon as you remain in the same library (to avoid circular references).

This can be a problem when you write code like this :

// BAD CODE
if(myProp is subclassA) 
{ ... 
} 
else if (myProp is syubclassB) 
{ ...
}

This code is bad, because you loose the advantage of inheritance.

Even in the .Net Framework there is such constructs. The first example that comes in my mind is the XObject.Parent property.

XElement inherits XObject, and XObject publish a property of type XElement. Same as your snippet.

Upvotes: 4

takrl
takrl

Reputation: 6472

You could do ...

interface IParent {
    ...
}

class Node {
    public IParent Parent {get; set;}
}

class File : Node {
    ...
}

class CategoryNode : Node, IParent {
    ...
}

This way, you don't need to refer to a derived object in the base class, plus, you're more flexible in what can actually become a parent, in case you get additional object types at a later point in time. Also, any functionality that is relevant just for a parent can be declared in that interface.

Upvotes: 7

Ivan Nikitin
Ivan Nikitin

Reputation: 4143

Other options will be to change class hierarchy to make the CategoryNode a root class (a), or change the property type to Node (b).

Both of these possibilities are not good: (a) File will have all functionality CategoryNode has which it doesn't need. (b) It will hide object type (which is always CategoryNode). This may follow to invalid cast errors somewhere else in your code. For example, if you forget there is always a CategoryNode instance.

Considering this, I believe current code is OK.

Upvotes: 1

Yochai Timmer
Yochai Timmer

Reputation: 49261

The base class shouldn't know who derives from it.

If you have such a case, you probably dont want inheritance. You should just use some form of coupling.

The File and CategoryNode should hold a Node member in your case.

Upvotes: 1

Related Questions