简体   繁体   中英

How can i create a super abstract class of 3 already present similar subclasses having different number of parameters in their constructors

I have 3 classes,

class ABCCache
{
    private float paramA;
    private float paramB;

    public ABCCache(float paramA, float paramB)
    {
        this.paramA = paramA;
        this.paramB = paramB;
    }

    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + Float.floatToIntBits(paramA);
        result = prime * result + Float.floatToIntBits(paramB);
        return result;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (obj instanceof ABCCache)
        {
            ABCCache other = (ABCCache) obj;
            return ((Float.floatToIntBits(paramA) == Float.floatToIntBits(other.paramA))
                && (Float.floatToIntBits(paramB) == Float.floatToIntBits(other.paramB)));
        }
        return false;
    }
}

class DEFCache
{
    private float paramD;
    private float paramE;
    private float paramF;

    public DEFCache(float paramD, float paramE, float paramF)
    {
        this.paramD = paramD;
        this.paramE = paramE;
        this.paramF = paramF;
    }

    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + Float.floatToIntBits(paramD);
        result = prime * result + Float.floatToIntBits(paramE);
        result = prime * result + Float.floatToIntBits(paramF);
        return result;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (obj instanceof DEFCache)
        {
            DEFCache other = (DEFCache) obj;
            return ((Float.floatToIntBits(paramD) == Float.floatToIntBits(other.paramD))
                && (Float.floatToIntBits(paramE) == Float.floatToIntBits(other.paramE))
                && (Float.floatToIntBits(paramF) == Float.floatToIntBits(other.paramF)));
        }
        return false;
    }
}

class XYZCache
{
    private float paramX;

    public XYZCache(float paramX)
    {
        this.paramX = paramX;
    }

    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + Float.floatToIntBits(paramX);
        return result;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (obj instanceof XYZCache)
        {
            XYZCache other = (XYZCache) obj;
            return (Float.floatToIntBits(paramX) == Float.floatToIntBits(other.paramX));
        }
        return false;
    }
}

All the 3 above classes stores cache of different types.

I have another class PerformCalculation as shown below:

public class PerformCalculation
{
    public static void main(String[] args)
    {

    }

    private float calculateABCValues(ABCCache abcCache)
    {
        //performOperation1
        return // perform Operation 2;
    }

    private float calculateDEFValues(DEFCache defCache)
    {
        //performOperation1
        return // perform Operation 2;
    }

    private float calculateXYZValues(XYZCache xyzCache)
    {
        //performOperation1
        return // perform Operation 2;
    }
}

There are three methods which performs the same operations on different objects. For removing code duplication, i want to have a single method where I can pass any of the three objects.

So I thought of creating a parent concrete class or abstract class of them, which I will provide as an argument to the single "calculateValues(ParentCache cache)".

I dont to want to create an empty parent Interface(Marker Interface) or AbstractClass, as it wont be recommended and just creating them for the sake of it is not correct.

How can I create a parent of these Subclasses.

You can make use of Java's runtime polymorphism as explained in the below steps:

(1) Define Cache interface

public interface Cache {
      T operation1();
      T operation2();
}

(2) Implement Cache classes which implement Cache interface

ABCCache implements Cache {
   public T operation1() {
     //code here
   }

    public T operation2() {
      //code here
    }
}

//Similarly implement other classes like DEFCache

(3) Define polymorphic calculateValues(Cache cache) method which takes any Cache type objects

public class PerformCalculation  {

      public static void main(String[] args)
      { 
           Cache cacheabc = new ABCCache();
           calculateValues(cacheabc);//calls ABCCache methods

           Cache cachedef = new DEFCache();
           calculateValues(cachedef);//calls DEFCache methods
        }

        //input argument is Cache (interface) type, 
        //so takes any methods which implement Cache interface (like ABCCache, etc..)
        private static float calculateValues(Cache cache)
        {
           cache.operation1();
           cache.operation2();
       }
   }

One point you need to learn in Java (or OOP supported languages) is coding to interfaces in order to make use of runtime polymorphism by which we can achieve dynamic behavior by passing different objects at runtime as shown above.

In other words, when you create the classes by implementing an interface (called coding to interfaces), you will get more flexibility so that you can inject the different objects (like how you passed ABCCache object, etc..) at runtime to the method (which accepts the interface type).

You can look at here for a similar subject matter.

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