Mohammad Kholghi
Mohammad Kholghi

Reputation: 783

Create a method to print child arrayList items in java

I have an abstract Person class which has 3 children: Admin, Employee and Student. There is only one admin object.

I also have a class which it's "name" is Statics and holds all public data I need, like this:

public class Statics {  

private static Person currentLoginUser;
private static ArrayList<Person> people = new ArrayList<>();
private static ArrayList<Student> students = new ArrayList<>();
private static ArrayList<Employee> employees = new ArrayList<>();
//We don't need ArrayList<Admin> because there is only one admin in the whole program

//Adder and getter methods:
//...
}

You may ask what ArrayList<Person> in the code is? When I create an object, I add it to both "it's own type arraylist" and "ArrayList<Person>". So ArrayList<Person> has everybody.

As I said, I only have 1 admin:

Person admin = new Admin(); //`Admin` extends `Person`

I want to create a method (in Admin class) which takes an arrayList of Person as input and prints it's data. So I did this:

//Admin class:
public void printList(ArrayList<Person> people){
//Do something
}

Let's assume admin wants to see the list of the students: I call it like this:

ArrayList<Student> s = Statics.getStudents();
((Admin)admin).printList(s); //admin object was created by `Person` class so I have to cast it to (Admin) to use `Admin`'s own methods.

It (eclipse) says that:

The method printList(ArrayList<Person>) in the type Admin is not applicable for the arguments (ArrayList<Student>)

I tried to cast it to person:

((Admin)admin).printList((ArrayList<Person>)s);

this time I got this error:

Cannot cast from ArrayList<Student> to ArrayList<Person>

In this link the answer is to pass the main arrayList and check if it's object's are from type "Student" or not, then print it's value but I don't want to check the whole Person arrayList everytime! I just want a method, which takes and arrayList of Person's children (Employee, Student, etc) and prints them.

Upvotes: 0

Views: 382

Answers (3)

Ganesh Thorat
Ganesh Thorat

Reputation: 592

As mentioned by @Abra problem is with generics. You can use generics in your code to fix your problem.

Create Admin class as a generic class and create printList method with List<T> list argument so that it will accept any type of object. e.g Person, Employee, Student etc.

This is just an example so please change your code accordingly.

public class Admin<T> {

  public void printList(List<T> list) {
   // Print list here
  }
}
    Statics stat = new Statics();
    Admin admin = new Admin<Student>();

    // Students
    admin.printList(stat.getStudents());
    // Employees
    admin.printList(stat.getEmployees());
    // People
    admin.printList(stat.getPeople());

Upvotes: 1

Denis Zavedeev
Denis Zavedeev

Reputation: 8307

Change printList method signature to:

public void printList(ArrayList<? extends Person> people)

Explanation:

Changing the signature will allow you to pass an ArrayList parameterized with Person or its subclasses.

In java the ? extends T construct is known as Upper Bounded Wildcards.

When using the people inside the printList method you will be able to "consume" (get) people from the list (but not to "produce" (add) them). "Consume" and "produce" are meant here in the PECS sense.


For more information about generics see Generics (Java tutorial)

Upvotes: 1

Abra
Abra

Reputation: 20924

Your problem is with generics. Even though Student extends Person, List<Student> does not extend List<Person>. That's why java generics has the wildcard which is represented with a ? (question mark).

If you use List<? extends Person> that means that each element in the list is an instance of either Person or any class that extends Person.

Refer to Generics, Inheritance, and Subtypes in the Generics lesson of the Learning the Java Language trail in Oracle's java tutorials.

Upvotes: 2

Related Questions