Polymorphism
Java polymorphism has many specific rules.
Overload concerns with static dispatch. Which method will be used is decided when compiling according the static type.
Override concerns with dynamic dispatch. Java requires the override method has the same name and parameter with the original method. Property cannot override.
With polymorphism, there is a special order to choose the exact method to use.
this.method(O)
>
>
> super.method(O)
>
>
> this.method((super)O)
>
>
> super.method((super)O)
If THIS is a super reference and the actual type is a lower class and the lower class has this override method, the override method will be chosen.
Generics
Generics is designed for special code reuse and actually it is rather complicated since its design sometimes conflicts with polymorphism. There is no generics in the JVM, all generics will be erased to the raw type and use type change to complement this design.
The significant result is that there is no relationships between super type and subtype when using generics since their raw type is same. However, the relationship can be construct over the generics use <? extends Type> or <? super Type>, which is not allowed in the definition.
What is more, the generics array become very complicated and it is strongly suggested to avoid combine generics with array.
Equality
Equality usually depends on the view of ADT. For one canon, we consider two objects are equal if they are mapped to the same image by Abstract Function. For another, we consider objects are equal when they have same behaviors under the identical operation.
For mutable class, Observation Equality allows two mutable objects with different reference to be the same if they have same attributes, like two same list. Behavioral Equality means the same reference I believe and it is recommended for mutable class.