Kyle V.
Kyle V.

Reputation: 4792

Have a Class and a Subclass handled the same way?

I have a class called Image and a class that extends it called ImageSheet.

ImageSheet is the same as Image except it has additional fields such as the number of frames on the sheet of images.

What I want to do is have it so I can call drawImage(img, frame) and have img be either a Image or an ImageSheet and handle them with the same method with the only difference being that if it's an Image then the frame field is ignored but when it's an ImageSheet the frame field is read and used to draw the specific frame.

I'm trying to avoid having separate methods for if it's an Image or an ImageSheet because I already have 3 different drawImage() methods that accept different input variables and if I did one for each class I'd have 3 pairs of methods where each pair is essentially exactly the same.

How can I pull off what I have in mind?

Upvotes: 0

Views: 101

Answers (4)

Alessandro Santini
Alessandro Santini

Reputation: 2003

From what I understand, the drawImage(...) methods are external to both Image and ImageSheet. In this case there are a number of potential solutions:

  • (This might be controversial) Image is in all effects an ImageSheet with a fixed number of frames (1); as such, you do not have to take care about Image being different;
  • If this solution is unsuitable, you may use a double dispatch, i.e. having the external renderer entity call a method drawImage(frame) (and possibly other variants, as I have understood from your words) declared in the Image class and as such present in every subclass; this is kind of similar to the Visitor pattern.
  • Last but not least, do not use an external renderer but have Images render themselves using a method drawImage(RenderingContext) where you can put all the possible feature requests of the rendering being performed.

Upvotes: 0

amfeng
amfeng

Reputation: 1073

Why don't you have the Image/ImageSheet classes handle the frame processing themselves?

For example, have the Image class have some method named process(frame) that then ignores the frame parameter sent in, and have ImageSheet override the process(frame) method with whatever processing you wanted the ImageSheet-specific object to do.

Then, you can have:

void drawImage(Image img, Frame frame) { img.process(frame); }

and it will do the appropriate thing depending on whether it's an Image or ImageSheet. Hope I'm understanding your question correctly!

Edit:

To clarify, here's the code for your Image and ImageSheet classes, respectively.

class Image {
  ... 
  public void process(Frame frame) { 
    // do something 
  }
}

class ImageSheet extends Image{
  ...
  // override process(Frame frame) method from Image
  public void process(Frame frame) { 
    // do something different 
  }
}

Upvotes: 1

Zapodot
Zapodot

Reputation: 462

As ImageSheet extends Image you can the signature on the drawImage(img, frame) method should be drawImage(Image img, Frame frame). To differentiate between Imageand ImageSheet objects use the instanceOf operator. Example:

public void drawImage(Image img, Frame frame) {
  if(img instanceof ImageSheet) {
    // handle ImageSheet
  } else {
    // handle all other Image instances
  }
}

Upvotes: 1

geneqew
geneqew

Reputation: 2581

I assume that drawImage is a method outside Image/ImageSheet and if you are avoiding a separate method, you may use instanceof and check if the img parameter is an instance of imageSheet.

Upvotes: 0

Related Questions