Home » Java » java – "actual and formal argument lists differ in length" error-Exceptionshub

java – "actual and formal argument lists differ in length" error-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

I’m trying to create a class that will do everything that a different class can do, but it will use random integers in order to create the objects that would normally require user input. Here I have a Pokemon program where I have class where the user creates a Pokemon trainer by inputting their name, and the program will create an ArrayList where the trainer’s Pokemon are stored. I have a subclass called ComputerTrainer where it should have the same functionality, but randomly generated Pokemon will be added to the trainer’s list of Pokemon. I created a constructor that accesses the protected variables in the PokemonTrainer class, but I’m getting an error that says “reason: actual and formal argument lists differ in length”. Why I am getting this error?

Here is the code for the PokemonTrainer class:

import java.util.ArrayList;
public class PokemonTrainer
{
    // private constants
    private static final int MAX_POKEMON = 2;
    protected ArrayList<Pokemon> pokemonList;
    protected String name;
    protected int numOfPokemon;

    // Write your PokemonTrainer class here
    public PokemonTrainer(String name)
    {
        this.name = name;
        pokemonList = new ArrayList<Pokemon>();
    }

    public boolean addPokemon(Pokemon p)
    {
        if(numOfPokemon < MAX_POKEMON)
        {
            pokemonList.add(p);
            numOfPokemon++;
            return true;
        }
        else
        {
            return false;
        }
    }

    public boolean hasLost()
    {
        int numOfPokemonThatLost = 0;
        for(Pokemon p : pokemonList)
        {
            if(p.hasFainted())
            {
                numOfPokemonThatLost++;
            }
        }
        if(numOfPokemonThatLost == numOfPokemon)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public Pokemon getNextPokemon()
    {
        int nextPokemon = 0;
        int numOfPokemonThatLost = 0;
        for(Pokemon p : pokemonList)
        {
            while(p.hasFainted() && nextPokemon < numOfPokemon)
            {
                nextPokemon++;
                numOfPokemonThatLost++;
                if(nextPokemon < numOfPokemon)
                {
                    p = pokemonList.get(nextPokemon);
                }
            }
        }
        if(numOfPokemonThatLost == numOfPokemon)
        {
            return null;
        }
        else
        {
            return pokemonList.get(nextPokemon);
        }
    }    

    public Pokemon getPokemon(int nPokemon)
    {
        return pokemonList.get(nPokemon);
    }

    public int getNumberOfPokemons()
    {
        return pokemonList.size();
    }

    public static int getMaxPokemon()
    {
        return MAX_POKEMON;
    }    

    public String toString()
    {
        return name;
    }
}

and here is the code for the ComputerTrainer subclass:

import java.util.ArrayList;
import java.util.Random;
public class ComputerTrainer extends PokemonTrainer
{
    // private constants
    // Possible pokemon names and move names to generate random Pokemon
    private static final String[] POKEMON_NAMES = {"Pikachu", "Bulbasaur", "Charmander", "Squirtle"};
    private static final String[] MOVE_NAMES = {"Tailwhip", "Bodyslam", "Splash", "Shock"};
    private static final int MAX_DAMAGE = 25;
    private static final int MAX_MOVES = 4;


    private PokemonImages images = new PokemonImages();

    // Write a Constructor that sets the name of the ComputerTrainer
    // and adds 2 randomly generated Pokemon to itself
    public ComputerTrainer(String name)
    {
        this.name = name;
        pokemonList = new ArrayList<Pokemon>();
        for(int i = 0; i < PokemonTrainer.getMaxPokemon(); i++)
        {
            Random num = new Random();
            int randomNumber = num.nextInt(POKEMON_NAMES.length);
            Pokemon p = new Pokemon (POKEMON_NAMES[randomNumber], images.getPokemonImage(POKEMON_NAMES[randomNumber]));
            pokemonList.add(p);
            numOfPokemon++;
        }
    }

    /*
     * Adds a randomly generated Pokemon to this ComputerTrainer's
     * collection of Pokemon. A ComputerTrainer can only have 2
     * Pokemon. This method returns true if there was room for the 
     * new Pokemon and it was successfully added, false otherwise.
     */
    public boolean addRandomPokemon()
    {
        if(numOfPokemon < PokemonTrainer.getMaxPokemon())
        {
            Random num = new Random();
            int randomNumber = num.nextInt(POKEMON_NAMES.length);
            Pokemon p = new Pokemon (POKEMON_NAMES[randomNumber], images.getPokemonImage(POKEMON_NAMES[randomNumber]));
            pokemonList.add(p);
            numOfPokemon++;
            return true;
        }
        else
        {
            return false;
        }
    }

    // Returns a Move randomly chosen from the set of Moves
    // that this trainer's current Pokemon knows.
    // If all Pokemon have fainted, returns null.
    public Move chooseRandomMove()
    {
        Pokemon currentBattlingPokemon = getNextPokemon();

        // This method isn't finished yet
    }
}

The program outputs the following error:

ComputerTrainer.java:20: error: constructor PokemonTrainer in class PokemonTrainer cannot be applied to given types;
    {
    ^
  required: String
  found: no arguments
  reason: actual and formal argument lists differ in length
How to&Answers:

The problem is that PokemonTrainer only has a constructor that has one String as parameter:

public class PokemonTrainer
{
    public PokemonTrainer(String name) {
        ...
}

but you are not calling that constructor from ComputerTrainer:

public class ComputerTrainer extends PokemonTrainer
{
    public ComputerTrainer(String name) {
        this.name = name;
        ...
    }
}

Java does not automatically call the constructor of the superclass that matches the actual constructor, it calls the default (parameter-less constructor) but the superclass does not have it.

Solution: add an explicit invokation of the correct constructor of the superclass:

public class ComputerTrainer extends PokemonTrainer
{
    public ComputerTrainer(String name) {
        super(name);
        ...
    }
}

see Java Language Specification 8.8.7. Constructor Body for more details

Note: the error message is a bit confusing since there is like a hidden super() call as first statement in the ComputerTrainer constructor