Up-casting is casting to a supertype, while downcasting is casting to a subtype. Upcasting and downcasting gives us advantages, like Polymorphism or grouping of different objects....
Up-casting and down-casting are great way of implementing polymorphism in your design. It is called as up-casting. Object 'p' has limited access. It can only access parent class properties, because p is a refernce to parent class.....
The main reason you'd do this is to decouple your code from a specific implementation of the interface. This is preferable because rest of the code only knows that data is of type List and hence you can switch between different implementations of the List interface with ease.....