简体   繁体   中英

Change classes in Java

I have a class ImageA, and a class ImageB. The both classes represents an image in my app, but each one in a different way. Even being different, their constructors are equal, and both have the method compare .

So, what I done was creating a class Image, and ImageA and ImageB are subClasses of Image.

public abstract class Image {
    protected String path;

    public Image(String path){
        this.path = path;
    }

    public abstract double compare(Image i2);
}


public class ImageA extends Image{...} 

public class ImageB extends Image{...}

But what I need is to test each implementation of image (ImageA and ImageB, in this case), to see the best one.

Is there a way to do this, changing my code at minimum? Suppose the objects used are from ImageA class, and I want to test now imageB class;

Obs.:

  • If all imageA objects of my app are setted by the type (ImageA i = new ImageA()), I'd have to change manually all in the code.

  • But even if I use the superType and cast it (Image i = (ImageA)new Image()), I'll have the same problem, to change the casts.

  • My question is different from this one: Refactoring abstract Java class with many child classes . In my case, the attributes inside the child classes are different, and I keep the attributes common to these classes in the Image class.

You could create a factory and pass an instance of your factory into the test class, using:

Image img = factory.newInstance(args);

throughout your test code. The factory determines which of the types ImageA or ImageB is used. An alternative would be to have a abstract Image newInstance(args) in your Image class and implement it in your subclasses. You would inject a first image instance into your test classes in that case.

Both methods rely on the fact that your args are the same between both types of images, you might need to pass in a superset to fulfill both constructors.

If this is an option (maybe I didn't get the question), you should use a factory method pattern to get the proper concrete class. The pizza sample is self explaining:

abstract class Pizza {
    public abstract int getPrice(); // count the cents
}

class HamAndMushroomPizza extends Pizza {
    public int getPrice() {
        return 850;
    }
}

class DeluxePizza extends Pizza {
    public int getPrice() {
        return 1050;
    }
}

class HawaiianPizza extends Pizza {
    public int getPrice() {
        return 1150;
    }
}

class PizzaFactory {
    public enum PizzaType {
        HamMushroom,
        Deluxe,
        Hawaiian
    }

    public static Pizza createPizza(PizzaType pizzaType) {
        switch (pizzaType) {
            case HamMushroom:
                return new HamAndMushroomPizza();
            case Deluxe:
                return new DeluxePizza();
            case Hawaiian:
                return new HawaiianPizza();
        }
        throw new IllegalArgumentException("The pizza type " + pizzaType + " is not recognized.");
    }
}

class PizzaLover {
    /*
     * Create all available pizzas and print their prices
     */
    public static void main (String args[]) {
        for (PizzaFactory.PizzaType pizzaType : PizzaFactory.PizzaType.values()) {
            System.out.println("Price of " + pizzaType + " is " + PizzaFactory.createPizza(pizzaType).getPrice());
        }
    }
}

Output:
Price of HamMushroom is 850
Price of Deluxe is 1050
Price of Hawaiian is 1150

I have some difficulty in understanding your question. I try here to summarize your problem statement,please comment if this is indeed what your question is.
(I would have put this as a comment but the number of characters exceed 600)

  • You have classes ImageA and ImageB that are subclasses of Image
  • Constructor for both these classes is the same and accepts a path argument (which I presume to be the path of image file)
  • Classes ImageA and ImageB use different attributes to represent the image
  • Common attributes classes ImageA and ImageB are kept in the base class (like the path attribute)
  • You declare an abstract method compare which takes an Image type as argument and returns a double value
  • The goal is to pass to compare method of ImageA a type of ImageB and the return value would indicate which concrete image representation is better. So this would mean that implementation of compare method should be such that, compare method in class ImageA will be called with instance of type ImageB and viceversa will be the implementation in class ImageB
  • The compare method in classes ImageA and ImageB cannot use methods in Image since they have different attributes

    If this problem statement indeed represents your problem, then I think is without resorting to checks like instanceof and casting it won't be possible to do the comparison between classes ImageA and ImageB . Though there is an abstract class Image the compare method still depends on what image attributes (which are not the same) the child classes use to represent an image.

  • 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