// Overloading versus Overriding in Object Oriented Programming class A { int f() { return 1; } } class B extends A { int f() { return 2; } // this is called OVERRIDING } public class overloadride { static int g(A x) { return 10; } static int g(B x) { return 20; } // this is OVERLOADING // OVERLOADING: Resolved by compiler using STATIC type information. // OVERRIDING: Resolved at runtime with dynamic type info (dynamic dispatch) public static void main(String[] args) { A n = new B(); // static type is A, dynamic type is B System.out.println(n.f()); // overriding (dynamic dispatch) calls B.f System.out.println(g(n)); //overloading, (static dispatch) calls g(A). // prints 2 then 10 } } /* Advanced object oriented programming requires dynamic type information and dynamic dispatch. an "A" object can either be an A object or a B object. For example, if we declared an array A[] N = { new A(), new B(), new A() }; What is the TYPE of N[i]? Is it A or B? That information does not exist until runtime, when the object is actually created (via 'new') and i is known. At compile time, the type of N[i] is A (superclass). So if the compiler is asked to resolve g(N[i]) it can only choose the version g(A x). Dynamic dispatch occurs if we call A[i].f(); The version of f to call is not decided at compile time at all. The compiler only checks that some f exists. The choice as to which one to call is made at runtime using the dynamic type information associated with each object. */ /* C++ version #include using namespace std; struct A { virtual int f() { return 1; } // note "virtual" }; struct B : public A { int f() override { return 2; } // note "override" }; int g(A* x) { return 10; } int g(B* x) { return 20; } int main() { A* n = new B(); cout << n->f() << endl; // prints 2 (overloading = dynamic dispatch) cout << g(n) << endl; // prints 10 (overriding = resolved statically). } In C++, to have the default behavior of Java we must 1. use public inheritance to establish "is a" relationship between B and A 2. use dynamic memory allocation (as opposed to stack allocation) because the compiler doesn't know exact type and size of object to be created. Only classes that contain virtual/override methods will have dynamic type information attached to objects at runtime, and the objects must be allocated on the heap. */