programming paradigm object orientation encapsulation inheritance polymorphism abstraction message passing class based prototype based composition object model class hierarchy modularity subtyping