Search code examples
javalinked-listsubclass

How can I pass a LinkedList of a sub class to function expecting LinkedList of the normal class?


I got a function that expects a LinkedList of objects, is it possible to pass and use a LinkedList of a sub-class of those objects?

public abstract class Car {...} //just for example

public class Audi extends Car {...}

public void showCars (LinkedList<Car> cars) {    //example function
    for (Car i : cars) {            
        System.out.println(i);
    }
}

public void test () {
    LinkedList<Audi> audis = new LinkedList<Audi>();

    audis.add(new Audi(...));    //just for example so that the list is not empty
    showCars(audis);              //this says that its expecting a LinkedList<Cars>
                                 //but got LinkedList<Audi>
}

It says that showCars expects LinkedList<Cars> but got LinkedList<Audi>. This is just a very simple code outline which hopefully shows my problem.


Solution

  • There are two ways of doing this:

    Change the accepting method signature

    The method you call should accept a list of Cars or its subclasses for this to work, and you have to define it that way. Change your showCars method signature to the following:

    public void showCars (LinkedList<? extends Car> cars)
    

    You can read https://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html for more information.

    Change the type of the list you pass as parameter

    Based on the rightful comment from @JohnBollinger, there is another way. You can declare your list as a list of cars, and send it to your method, instead of a list of Audis:

    public abstract class Car {...} //just for example
    
    public class Audi extends Car {...}
    
    public void showCars (LinkedList<Car> cars) {    //example function
        for (Car i : cars) {            
            System.out.println(i);
        }
    }
    
    public void test () {
        LinkedList<Car> audis = new LinkedList<>();
    
        audis.add(new Audi(...));    //just for example so that the list is not empty
        showCars(audis);              //this says that its expecting a LinkedList<Cars>
                                     //but got LinkedList<Audi>
    }
    

    Remember than a list with a Class generic type will accept also objects of its subclasses.This would preserve the original method signature and leave the responsibility on the caller to provide the properly typed LinkedList. This would also be the proper way to do this when the method you are calling is provided by a library or other source you have no access to.