hardywang
hardywang

Reputation: 5172

I need to 2 levels of inheritance and abstraction in master-child relationship

Let's assume I have a business case I want to use some model to represent a master-child structure. And there will be certain classes to inherit from both the master class and child class.

I use the sample below

public abstract class BaseChild
{
    public int MyProperty { get; set; }
}

public abstract class BaseMaster
{
    public abstract ReadOnlyCollection<BaseChild> Children { get; }
}

Now I need real classes to inherit from them. So have following

public class FirstRealChild : BaseChild
{
    public int AdditionalProperty { get; set; }
}

public class FirstRealMaster : BaseMaster
{
    public ReadOnlyCollection<FirstRealChild> Children { get; }
}

Of course it won't compile because of the error

'FirstRealMaster' does not implement inherited abstract member 'BaseMaster.Children.get'

I can remove the public abstract ReadOnlyCollection<BaseChild> Children { get; } from BaseMaster class, but it loses the constraint to all inherited classes that children are required.

Anybody has some better idea?

Upvotes: 1

Views: 167

Answers (2)

Henk Holterman
Henk Holterman

Reputation: 273464

You may get somewhere with generics:

public abstract class BaseMaster<TChild> where TCHild : BaseChild
{
    // this probably doesn't have to be 'abstract' anymore
    public abstract ReadOnlyCollection<TChild> Children { get; }
}

public class FirstRealMaster : BaseMaster<FirstRealChild>
{
}

But we don't know enough about the relation between Master and Child classes to be sure.

Upvotes: 3

Alexei Levenkov
Alexei Levenkov

Reputation: 100545

Generics + potentially non-generic base class for your "with children" type is the standard solution. If you don't need BaseMaster to be assignment-compatible between different types of child nodes you can remove base non-generic class.

Something roughly like following:

public class BaseMaster
{
    public ReadOnlyCollection<BaseChild> Children { get; }
}

public class BaseMaster<T> : BaseMaster where T: BaseChild
{
    public new IEnumerable<T> Children { get
        {
           return base.Children.Cast<T>();
        };
    }
}

Upvotes: 0

Related Questions