Reputation: 3350
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.
Upvotes: 1
Views: 7903
Reputation: 28683
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)
ImageA
and ImageB
that are subclasses of Image
ImageA
and ImageB
use different attributes to represent the image
ImageA
and ImageB
are kept in the base class (like the path attribute)
compare
which takes an Image
type as argument and
returns a double value
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
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.
Upvotes: 1
Reputation: 570365
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
Upvotes: 3
Reputation: 23373
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.
Upvotes: 3