SZT
SZT

Reputation: 1966

Abstract classes share properties, any way to put them in one place?

I have two abstract classes that has couple of same properties. How can I put them in just one common place?

public abstract class ClassA
{
     public abstract string PropertyA {get; }
     public abstract string PropertyB {get; }          
     public string PropertyX {get; set;}
     public void MethodA()
     {
         // do something
     }          
}


public abstract class ClassB
{
     public abstract string PropertyA {get; }
     public abstract string PropertyB {get; }          
     public string PropertyY {get; set;}          
     public void MethodB()
     {
         // do something else
     }
}

public class ClassC1 : ClassA
{
     public string PropertyA {get {return "MyString";} }
     public string PropertyB {get{return "MyOtherString";} }          

}

public class ClassC2 : ClassA
{
     public string PropertyA {get {return "MyString2";} }
     public string PropertyB {get{return "MyOtherString2";} }          

}

public class ClassD1 : ClassB
{
     public string PropertyA {get {return "MyString";} }
     public string PropertyB {get{return "MyOtherString";} }          
}

public class ClassD2 : ClassB
{
     public string PropertyA {get {return "MyString2";} }
     public string PropertyB {get{return "MyOtherString2";} }          
}

This is my scenario. Now since PropertyA and PropertyB returns the same value for both class, I was wondering if there's any way I can refactor the classes so I don't have put the same properties in both abstract/concrete classes.

Upvotes: 0

Views: 536

Answers (4)

Jamie
Jamie

Reputation: 115

This solution doesn't remove the string properties from the sub classes, it does however remove the duplicate string values.

Now they can be configured in "CustomProperties" class once then reused.

See below.

Favour Composition over inheritance

public class CustomProperties
{
    public string PropertyA { get; private set; }
    public string PropertyB { get; private set; }
}

public interface ICustomProperties
{
      string PropertyA { get; }
      string PropertyB { get; }
}

public abstract class ClassA : ICustomProperties
{
    private readonly CustomProperties properties;

    public ClassA(CustomProperties properties)
    {
        this.properties = properties;
    }

    public string PropertyA
    {
        get { return properties.PropertyA; }
    }

    public string PropertyB
    {
        get { return properties.PropertyB; }
    }

    public string PropertyX { get; set; }

    public void MethodA()
    {
        // do something
    }
}

Upvotes: 1

Aleksey L.
Aleksey L.

Reputation: 37988

Not sure if ClassA and B can derive from the same base, but if yes you can go like this:

public class CommonAB
{
    public string PropertyA { get; private set; }
    public string PropertyB { get; private set; }

    public CommonAB(string a, string b)
    {
        PropertyA = a;
        PropertyB = b;
    }
}

public class ClassA : CommonAB
{
    public ClassA(string a, string b)
        : base(a, b)
    {
    }

    public string PropertyX { get; set; }
    public void MethodA()
    {
        // do something
    }
}


public class ClassB : CommonAB
{
    public ClassB(string a, string b)
        : base(a, b)
    {
    }

    public string PropertyY { get; set; }
    public void MethodB()
    {
        // do something else
    }
}

public class ClassC1 : ClassA
{
    public ClassC1()
        : base("MyString", "MyOtherString")
    {
    }
}

public class ClassC2 : ClassA
{
    public ClassC2()
        : base("MyString2", "MyOtherString2")
    {
    }
}

public class ClassD1 : ClassB
{
    public ClassD1()
        : base("MyString", "MyOtherString")
    {
    }
}

public class ClassD2 : ClassB
{
    public ClassD2()
        : base("MyString2", "MyOtherString2")
    {
    }
}

Upvotes: 0

user2726374
user2726374

Reputation: 46

In addition to Adil answer, Can you make your methods abstract or virtual and override them in your derived class?

Upvotes: 0

Adil
Adil

Reputation: 148150

Make a common abstract class with and inherit rest from that

public abstract class ClassCommon
{
     public abstract string PropertyA {get; }
     public abstract string PropertyB {get; }          
}

public abstract class ClassA : ClassCommon
{              
     public string PropertyX {get; set;}          
}


public abstract class ClassB : ClassA
{     public string PropertyY {get; set;}          
}

You can override the properties instead of using base class properties.

public class ClassC1 : ClassCommon
{
     public override string PropertyA {get {return "MyString";} }
     public override string PropertyB {get{return "MyOtherString";} }              
}

Upvotes: 1

Related Questions