简体   繁体   中英

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.

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";} }              
}

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
    }
}

除了Adil答案之外,您还可以将方法抽象或虚化,并在派生类中覆盖它们吗?

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")
    {
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM