ArrayList has an add(Object ) method. But in the given code, we are using ArrayList<Book>, which means that ArrayList has been parameterized to use Book and so, from the compiler's perspective, ArrayList<Book> now has as add(Book ) method (instead of add(Object ) ).
Next, we have defined BookList to extend from ArrayList<Book>, this means that if we want to override the add(Book ) method in the BookList class, we need to define it as add(Book ). If we define it as add(Object ), the compiler will consider it an overload (because base class has add(Book ) and subclass has add(Object ) ). However, this overload will not work for the JVM because generics are not reified. The JVM doesn't see the generic information and so it doesn't know that anything like ArrayList<Book> exists. It only knows about ArrayList.
So, now you can see that there is a contradiction - from compiler's perspective it is a overload but from the JVM's perspective it is an override. To avoid this contradiction, the compiler doesn't allow it.
If you are not sure about reification in generics, you will need to go through a good book to read about it first.
If you like our products and services, please help us by posting your review here.