Search code examples
javaclassobjectinheritancearraylist

How to modify an item from array list for inherited class?


I am making a zoo management system where I can add an animal, modify an animal, delete an animal, and print an animal. I am using a dynamic array called ArrayList for this project. My problem is that I am not able to modify elements in the inherited class. However I am able to modify the elements in the parent class.
This is my parent class:

public abstract class Animals {
    String name, animalID, type, food;
    int age;

    Animals(String name, String animalID, String type, String food, int age)
    {
        this.name = name;
        this.animalID = animalID;
        this.type = type;
        this.food = food;
        this.age = age;
    }

    Animals()
    {
        this ("No Name", "No Animal ID","No Type Specified","No Food Specified",-1);
    }

    public abstract String getName();
    public abstract void setName(String name);
    public abstract String getAnimalID();
    public abstract void setAnimalID(String animalID);
    public abstract String getType();
    public abstract void setType(String type);
    public abstract String getFood();
    public abstract void setFood(String food);
    public abstract int getAge();
    public abstract void setAge(int age);
    public abstract void print();
}

This is my inherited class:

public class Birds extends Animals {
    String furColour, importLocation;
    int cageNumber;

    Birds(String name, String animalID, String type, String food, int age,String furColour, String importLocation, int cageNumber)
    {
        super(name,animalID,type,food,age);
        this.furColour = furColour;
        this.importLocation = importLocation;
        this.cageNumber = cageNumber;
    }

    Birds ()
    {
        this (null,null,null,null,0,"No Fur Colour Specified","No Import Location Specified",-1);
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String getAnimalID() {
        return animalID;
    }

    @Override
    public void setAnimalID(String animalID) {
        this.animalID = animalID;
    }

    @Override
    public String getType() {
        return type;
    }

    @Override
    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String getFood() {
        return food;
    }

    @Override
    public void setFood(String food) {
        this.food = food;
    }

    @Override
    public int getAge() {
        return age;
    }

    @Override
    public void setAge(int age) {
        this.age = age;
    }

    public String getFurColour() {
        return furColour;
    }

    public void setFurColour(String furColour) {
        this.furColour = furColour;
    }

    public String getImportLocation() {
        return importLocation;
    }

    public void setImportLocation(String importLocation) {
        this.importLocation = importLocation;
    }

    public int getCageNumber() {
        return cageNumber;
    }

    public void setCageNumber(int cageNumber) {
        this.cageNumber = cageNumber;
    }

    @Override
    public void print()
    {
        System.out.println("Name: "+name+"\nAnimal ID: "+animalID+"\nType "+type+"\nFood: "+food+"\nAge: "+age+"\nFur Colour: "+furColour+"\nImport Location: "+importLocation+"\nCage Number: "+cageNumber+"\n");
    }
}

Now, assuming that the information of a particular bird already exists in the array list at index 5, for example, how do I modify the fur color information for the bird at index 5?

This is my modify function so far:

static public void modify()
    {
        System.out.print("Enter Animal ID: ");
        String modifyId = input.next();
        for (int i=0; i<zooAnimals.size(); i++)
        {
            if (zooAnimals.get(i).getAnimalID().equals(modifyId))
            {
                System.out.println("Animal Modify Menu\n------------------------------");
                String animalType = zooAnimals.get(i).getType();
                switch (animalType)
                {
                    case "Bird": modifyBird(i,modifyId);
                        break;
                    case "Monkey": modifyMonkey(i);
                        break;
                    case "Lion": modifyLion(i);
                        break;
                }
            }
            else
            {
                System.out.println("Animal Id does not exist");
            }
        }
    }

static public void modifyMenu()
{
    System.out.println("A. Change Name");
    System.out.println("B. Change ID");
    System.out.println("C. Change Food");
    System.out.println("D. Change Age");
}
static public void modifyBird(int animalIndex, String id)
{
    char birdSelect;
    boolean continueLoop = true;
    do
    {
        modifyMenu();
        System.out.println("E. Change Fur Colour");
        System.out.println("F. Change Import Location");
        System.out.println("G. Change Cage Number");
        System.out.println("H. Back to Main Menu");
        System.out.print("Choose an option: ");
        birdSelect = input.next().charAt(0);
        switch (birdSelect)
        {
            case 'a':
            case 'A': System.out.print("Enter New Name: ");
                         String newName = input.next();
                         zooAnimals.get(animalIndex).setName(newName);
                         System.out.println("Name Changed!");
                break;
            case 'b':
            case 'B': System.out.print("Enter New ID: ");
                        String newId = input.next();
                        zooAnimals.get(animalIndex).setAnimalID(newId);
                         System.out.println("ID Changed!");
                break;
            case 'c':
            case 'C': System.out.print("Enter New Food: ");
                        String newFood = input.next();
                        zooAnimals.get(animalIndex).setFood(newFood);
                         System.out.println("Food Changed!");
                break;
            case 'd':
            case 'D': System.out.print("Enter New Age: ");
                        int newAge = input.nextInt();
                        zooAnimals.get(animalIndex).setAge(newAge);
                         System.out.println("Age Changed!");
                break;
            case 'e':
            case 'E': System.out.print("Enter New Fur Colour");
                         String newColour = input.next();
                         //zooAnimals.get(animalIndex).setFurColour = newColour;
                         //How do I do this?
                break;
            case 'f':
            case 'F':
                break;
            case 'g':
            case 'G':
                break;
            case 'h':
            case 'H':
                break;
            default: System.out.println("Please choose a valid option!");
            break;
        }
    } while (continueLoop);
}

static public void modifyMonkey(int animalIndex)
{
    modifyMenu();
}

static public void modifyLion(int animalIndex)
{
    modifyMenu();
}

This is my add function, to understand my code better:

static public void add()
{
    boolean continueLoop = true;
    do
    {
        System.out.println();
        System.out.println("Add Menu\n----------------");
        System.out.println("A. Add a Bird");
        System.out.println("B. Add a Monkey");
        System.out.println("C. Add a Lion");
        System.out.println("D. Back to Main Menu");
        System.out.print("Choose an Option: ");
        char animalType = input.next().charAt(0);
        System.out.println();
        if (animalType == 'd' || animalType == 'D')
        {
            System.out.println();
            menu();
        }
        else
        {
            System.out.print("Enter Animal Name: ");
            String animalName = input.next();
            System.out.print("\nEnter Animal ID: ");
            String animalId = input.next();
            System.out.print("\nEnter Animal Food: ");
            String animalFood = input.next();
            boolean isNumber;
            System.out.print("\nEnter Animal Age: ");
            do
            {
                if (input.hasNextInt())
                {
                    int animalAge = input.nextInt();
                    isNumber = true;
                    System.out.println();
                    switch (animalType)
                    {
                        case 'a':
                        case 'A': addBird(animalName,animalId,"Bird",animalFood,animalAge);
                            break;
                        case 'b':
                        case 'B': addMonkey(animalName,animalId,"Monkey",animalFood,animalAge);
                            break;
                        case 'c':
                        case 'C': addLion(animalName,animalId,"Lion",animalFood,animalAge);
                            break;
                        case 'd':
                        case 'D': menu();
                            break;
                        default: System.out.println("Please choose a valid option");
                            break;
                    }
                }
                else
                {
                    System.out.println("Invalid Input! Please Enter Again");
                    isNumber = false;
                    input.next();
                }
            } while (!(isNumber));
         }  
    } while (continueLoop);
}

static public void addBird(String name, String animalID, String type, String food, int age)
{
    Animals b;
    System.out.print("Enter Bird's Fur Colour: ");
    String birdColour = input.next();
    System.out.print("\nEnter Bird's Imported Location: ");
    String birdLoc = input.next();
    System.out.print("\nEnter Bird's Cage Number: ");
    boolean isNumber;
    do
    {
        if (input.hasNextInt())
        {
            int birdCageNum = input.nextInt();
            isNumber = true;
            b = new Birds(name,animalID,type,food,age,birdColour,birdLoc,birdCageNum);
            zooAnimals.add(b);
        }
        else
        {
            System.out.println("Enter an Integer Number!\nEnter again: ");
            isNumber = false;
            input.next();
        }
    } while (!(isNumber));
}

static public void addMonkey(String name, String animalID, String type,String food, int age)
{
    Animals m;
    System.out.print("Enter Monkey's Behaviour (Wild, Normal, Calm): ");
    String behaviour = input.next();
    System.out.print("\nEnter Number of Offsprings: ");
    boolean isNumber;
    do
    {
        if (input.hasNextInt())
        {
            int offsprtingNum = input.nextInt();
            isNumber = true;
            m = new Monkey(name,animalID,type,food,age,behaviour,offsprtingNum);
            zooAnimals.add(m);
        }
        else
        {
            System.out.println("Enter an Integer Number!\nEnter again: ");
            isNumber = false;
            input.next();
        }
    } while (!(isNumber));
}

static public void addLion(String name, String animalID, String type,String food, int age)
{
    Animals l;
    System.out.print("Enter Lion's Health (Strong, Normal, Weak): ");
    String health = input.next();
    System.out.print("Enter Number of Meats eaten: ");
    boolean isNumber;
    do
    {
        if (input.hasNextInt())
        {
            int meatNumber = input.nextInt();
            isNumber = true;
            l = new Lion(name, animalID, type, food,age,health, meatNumber);
            zooAnimals.add(l);
        }
        else
        {
            System.out.print("\nInvalid Input!\nEnter Again:");
            isNumber = false;
            input.next();
        }
    } while (!(isNumber));
}

Solution

  • It sounds like your ArrayList is of type Animals, and you want to invoke a method on one of its elements that's defined on the Birds class. After retrieving the element, simply cast it to type Birds and then invoke the relevant method:

    ((Birds) zooAnimals.get(animalIndex)).setFurColour(newColour);
    

    Casting simply tells the compiler what the underlying type of the object is, so that you can access the methods on that type. The official Java tutorial on inheritance has more details on how type casting works.

    As an aside, your class names should generally be singular (Bird, Animal), rather than plural, as a matter of convention.