CrystalRain
CrystalRain

Reputation: 82

Using childclass attributes with parentclass method

Okay, I'm pretty sure I'm missing something here, but this is my problem: I have an abstract parent class, in which I have a defined(not abstract) method, which is the same for all subclasses. Problem is, it needs to access the attributes of the subclass object it is called with. But it doesn't do that and instead uses the (non-defined) attributes of the abstract class.

I feel like there's an easy solution to that, but I can't think of it.

Code parent:

public abstract class Background
{
    private boolean fadeTriggered;
    private int flagFade;

    public void checkFade(Background fadeFrom, Background fadeInto, SpriteBatch batch, ParallaxBackground parallaxBackground) {
        //Clean up
        if (fadeFrom.getFadeTriggered()) {
            fadeFrom.setFadeTriggered(false);
            if (fadeFrom.getFlagFade() > 0) {
                fadeFrom.setFlagFade(0);
            }
        }

        //Fade
        if (!fadeTriggered) {
            fadeTriggered = true;
            flagFade = 1000;
        }

        if (flagFade > 0) {
            parallaxBackground.draw(batch, this.getID(), 1);
            parallaxBackground.draw(batch, fadeInto.getID(), flagFade * .001f);
            flagFade--;
        } else {
            parallaxBackground.draw(batch, this.getID(), 1f);
        }
    }
}

Code Child:

public class BackgroundSnow extends Background {

    private ArrayList<ParallaxTexture> textures;
    private int textureCount;
    private final String biomeName = "Default";
    private final int id = 1;
    protected boolean fadeTriggered = false;
    protected int flagFade = 0;


    public BackgroundSnow() {
        int i = 1;

        while (true) {
            if (!Gdx.files.internal("backgrounds/parallax/" + biomeName + "/img" + i + ".png").exists()) {
                this.textureCount = i - 1;
                break;
            }
            i++;
        }

        Printer.debugPrintToConsole(ParallaxBackground.class, "Parallax Backgrounds found: " + Integer.toString(textureCount));

        textures = new ArrayList<>();

        for (int j = 1; j < textureCount + 1; j++) {
            textures.add(new ParallaxTexture(j, biomeName));

        }
    }
}

and then you call checkFade with some instance of the childclass

Upvotes: 1

Views: 86

Answers (3)

Daniele
Daniele

Reputation: 2837

You should not have the same fields both private in the parent class and protected in the child class, that is a source of confusion.

If possible, remove the protected fadeTriggered and flagFade from the child, move the getters and setters to the parent class (or create them if missing), and you should be good.

And for cleanliness, use the getters and setters in the parent class also, when accessing those fields.

Upvotes: 3

jacobm
jacobm

Reputation: 14035

There are a couple ways to approach this.

One way is to give your abstract base class a constructor, forcing children to give it the values it needs:

public abstract class Background {
  private boolean fadeTriggered;
  private int flagFade;
  public Background(boolean fadeTriggered, int flagFade) {
    this.fadeTriggered = fadeTriggered;
    this.flagFade = flagFade;
  }

  // Now use your own copies of the fields as needed
}

Another way is to require subclasses to define getter methods for the fields you're interested in:

public abstract class Background {
  protected abstract boolean fadeTriggered();
  protected abstract int flagFade();


  // Call getters to access child values
}

Upvotes: 1

Max Vollmer
Max Vollmer

Reputation: 8598

The problem is that you have fadeTriggered and flagFade twice, once in the parent class and once in the child class.

Now you probably have some code in your child class that sets its fadeTriggered and flagFade, but never does anything with the parent's fadeTriggered and flagFade, while the parent's checkFade method accesses the parent's fadeTriggered and flagFade (which are never touched).

To solve this you need to get rid of the duplicate members in your child class, and set the parent's members instead.

I recommend adding protected setters to the parent class:

protected setFadeTriggered(boolean fadeTriggered) {
    this.fadeTriggered = fadeTriggered;
}

protected setFlagFade(boolean flagFade) {
    this.flagFade = flagFade;
}

or make them public if you have external classes setting these values.

Upvotes: 1

Related Questions