cksanjose
cksanjose

Reputation: 461

How to have the base class be aware of derived class properties?

I'm trying to create a base class that will be used in storing data in key/value manner. The base class will generate the keys and is responsible for storing the data. When the base class is inherited, the derived class can specify it's own key but the the base class has to be aware of the derived classes' key. For example:

public class ParentClass
{
   private string key = "Parent";

   public void GenerateKey()
   {
       Console.WriteLine(key);
   }
}

public class FeatureClass : ParentClass
{
   public string key = "Feature";

}

public class SubFeatureClass : FeatureClass 
{
   public string key = "SubFeature";

}

FeatureClass feature = new FeatureClass();
feature.GenerateKey(); //I would like this to produce "Parent_Feature"

SubFeatureClass subFeature = new SubFeatureClass();
subFeatureClass.GenerateKey(); //I would like this to generate "Parent_Feature_SubFeature"

How can I make the base class be aware of its children's keys regardless of how many levels of inheritance has occurred.

Upvotes: 1

Views: 138

Answers (6)

Dmitriy Khaykin
Dmitriy Khaykin

Reputation: 5258

Using constructor overloading and constructor chaining in my version:

public class ParentClass
{
    private string key;

    protected ParentClass(string childKeys)
    {
        key = !string.IsNullOrEmpty(childKeys) ? key + "Parent_" + childKeys : key;
    }

    public void GenerateKey()
    {
        // Get keys from subclasses
        Console.WriteLine(key);

    }
}

public class FeatureClass : ParentClass
{
    public FeatureClass() : base("Feature") { }
    protected FeatureClass(string key) : base("Feature_" + key) { }
}

public class SubFeatureClass : FeatureClass 
{
    public SubFeatureClass() : base("SubFeature") { }
    protected SubFeatureClass(string key) : base("SubFeature_" + key) { }
}

public class ReallySubFeatureClass : SubFeatureClass
{
    public ReallySubFeatureClass() : base("ReallySubFeature") { }
}

Test code looks just like yours but I added one more level for example:

class Program
{
    static void Main(string[] args)
    {
        FeatureClass feature = new FeatureClass();
        feature.GenerateKey(); //I would like this to produce "Parent_Feature"

        SubFeatureClass subFeature = new SubFeatureClass();
        subFeature.GenerateKey(); //I would like this to generate "Parent_Feature_SubFeature"

        ReallySubFeatureClass reallySubFeature = new ReallySubFeatureClass();
        reallySubFeature.GenerateKey();

        Console.ReadKey();
    }
}

Result:

enter image description here

Upvotes: 0

T. Kiley
T. Kiley

Reputation: 2802

Abstract or virtual functions can be used to achieve this (which one depends on whether it makes sense for ParentClass to be the actual type or whether it always needs a derived class.

In any case, you would have a virtual (or abstract) function which you override in the derived class to return the special key. In fact, in C# you can have virtual/abstract properties:

public abstract class ParentClass
{
   private string key = "Parent";

   protected abstract string derivedKey
   {
        get;
   }

   public void GenerateKey()
   {
       Console.WriteLine(key + derivedKey);
   }
}

public class FeatureClass : ParentClass
{
   public override string derivedKey
   {
        get
        {
             return "Feature";
        }
    }

}

Upvotes: 0

halit
halit

Reputation: 1128

public class ParentClass
{
    protected List<string> keys = new List<string>();

    public ParentClass()
    {
        keys.Add("Parent");
    }

    public void GenerateKey()
    {
        Console.WriteLine(string.Join("_", keys));
    }
}

public class FeatureClass : ParentClass
{
    public FeatureClass()
    {
        keys.Add("Feature");
    }
}

public class SubFeatureClass : FeatureClass
{
    public SubFeatureClass()
    {
        keys.Add("SubFeature");
    }

}

Upvotes: 0

Servy
Servy

Reputation: 203802

Use a virtual property instead of a field:

public class ParentClass
{
   public ParentClass(){Key = "Parent";}
   private virtual string Key {get;set;}

   public void GenerateKey()
   {
       Console.WriteLine(Key);
   }
}

public class FeatureClass : ParentClass
{
    public FeatureClass(){Key = base.Key + "_" + "Feature";}
    override string Key {get;set;}
}

Upvotes: 0

rae1
rae1

Reputation: 6134

You could do this, using virtual properties,

public class ParentClass
{
    public virtual string Key
    {
        get
        {
            return "Parent";
        }
    }
}

public class FeatureClass : ParentClass
{
    public override string Key
    {
        get
        {
            return base.Key + "_" + "Feature";
        }
    }

}

public class SubFeatureClass : FeatureClass 
{
    public override string Key
    {
        get
        {
            return base.Key + "_" + "SubFeature";
        }
    }
}

Then, you could use it this way,

FeatureClass feature = new FeatureClass();
Console.WriteLine(feature.Key); // <-- "Parent_Feature"

SubFeatureClass subFeature = new SubFeatureClass();
Console.WriteLine(subFeature.Key); // <-- "Parent_Feature_SubFeature"

Upvotes: 0

D Stanley
D Stanley

Reputation: 152491

You can do this by making the base method virtual and referencing it in the override:

public class ParentClass
{
   public virtual string key {get {return "Parent";}}

   public void GenerateKey()
   {
       Console.WriteLine(key);
   }
}

public class FeatureClass : ParentClass
{
   public override string key {get{return base.key +  "_Feature";}}

}

public class SubFeatureClass : FeatureClass 
{
   public override string key {get{return base.key +  "_SubFeature";}}

}

Upvotes: 4

Related Questions