An example of why this warning or error is important consider the following example:
package a;
public class Animal {
// Note: no visibility modifier therefore package-private
String makeNoise() {
return "no noise defined";
}
}
package b;
import a.Animal;
public class Cat extends Animal {
// Note: Eclipse will show the warning that it doesn't override
public String makeNoise() {
return "meow";
}
}
package b;
import a.Animal;
public class Dog extends Animal {
// Note: Eclipse will show the warning that it doesn't override
public String makeNoise() {
return "bark";
}
}
package a;
import java.util.ArrayList;
import java.util.List;
import b.Cat;
import b.Dog;
public class Main {
public static void main(String[] args) {
// Make a list of Animals
List<Animal> animals = new ArrayList<>();
animals.add(new Cat());
animals.add(new Dog());
// Loop through the animals making their noises
for (Animal animal : animals) {
System.out.println(animal.makeNoise());
}
}
}
Copy paste the whole thing into Eclipse and it will sort out the classes and packages. Then run the Main
class. You might expect it to print
meow
bark
But instead it prints
no noise defined
no noise defined
This is confusing behaviour which unexpectedly breaks polymorphism. The reason it does this is the Animal
subclasses Cat
and Dog
have not actually overridden the method makeNoise
at all, so when makeNoise
is called on an Animal
it uses the Animal
implementation.
To fix this code add public
or protected
modifiers to the Animal
makeNoise
method, then rerun the code it will now work as expected. In this simple example its quite clear what is going on, but in a more complicated situation this behaviour could be extremely confusing and probably incorrect so the warning should be taken seriously.