I have a question on casting. The process of valid upcasting and downcasting is plain:
When two classes are not in the same inheritance branch, it is also quiet clear, the compiler will throw a compilation error. But what about interfaces? Why the code snippet below regarding 'Phone' instance and 'Roamable' interface compiles fine?
thats why reference type Phone may contain class iPhone that implement interface Roamable. and as you can store object iPhone in Phone you can cast it to interface Roamable.
thats behavior will nullify if you mark Phone as final.
That can be summarized in a very simple rule: if your class ClassX isn't final, you can cast a reference variable of ClassX to any interface. If ClassX is final, casting to any interface not implemented by ClassX (or its parent classes) will result in a compiler error.
The reason behind this rule is also very easy and makes a lot of sense: if ClassX isn't final, ClassY can extend ClassX and implement InterfaceA which isn't implemented by ClassX. Therefore a reference variable of ClassX can refer to a ClassY instance, and then the cast to InterfaceA is valid (and no compiler error should be given). This scenario is also illustrated with a code example in the post of Sergej Smoljanov. If ClassX is final, the compiler knows this class can't be subclassed and thus the cast is invalid and the compiler gives one of his shiny errors