140 likes | 312 Views
Lecture 11: Polymorphism and Dynamic Binding. Polymorphism Static (compile-time) binding Dynamic (run-time) binding. Polymorphism. A fundamental feature of OOP Greek for many shapes Idea: one abstract operation is implemented differently for different classes Example: toString method
E N D
Lecture 11: Polymorphism and Dynamic Binding • Polymorphism • Static (compile-time) binding • Dynamic (run-time) binding
Polymorphism • A fundamental feature of OOP • Greek for many shapes • Idea: one abstract operation is implemented differently for different classes • Example: toString method • x.toString() calls different implementations of the toString method depending on whether x is an object reference of class Object, String, Date, Time, etc • aside: toString is called by System.out.println(x) when x is an object reference • in other words, System.out.println(x) has the same effect as System.out.println(x.toString())
The Words Static and Dynamic • These words are opposites • Static means fixed, unchanging • Dynamic means changing with time • Static variable of a class: value does not depend on individual objects (instances) of a class • Static method of a class: effect does not depend on individual objects (instances) of a class • Static binding (this term not used by text): binding a method call to the right method implementation at compile time • Dynamic binding (this term is used by text): binding a method call to the right method implementation at run time
Static (Compile-Time) Binding • Binding a method call to the right method implementation at compile-time • This is possible for static methods because it depends only on matching the argument types to the method signature • NOT POSSIBLE for instance methods, because at compile-time we only know the type of the object reference, NOT the actual class of the object instance
Example • Object o = new Time(); • Date d = new Time(); • Time t = new Time(); • System.out.println(o.toString()); • System.out.println(d.toString()); • System.out.println(t.toString()); • Which toString is called? • Does it know which one to call at compile time, or only at run time?
Dynamic Binding • Used for instance methods • Actual class of object is not known at compile time, only at run time • Then, binding of method call to the right implementation of the method takes place, based on the class of the implicit parameter object • Which method is called when o.toString() is executed does not depend on type of the object reference o, but on the actual class of the object that it points to • When execution takes place, the JVM looks for a matching method in that class. If there isn’t one, it looks in the superclass, and so on….if there are none in the inheritance tree below Object, it will use the toString method in the Object class
What about the Explicit Parameters? • The method binding does not depend on the class of any object that is passed as an explicit parameter! • Thus, which implementation of x.equals(y) is called • depends on the class of the object instance that the implicit parameter x points to • does notdepend on the class of the object instance that the explicit parameter y points to • However, the method signatures must match!
Matching the Method Signatures • Consider x.equals(y) • Which method is called depends on the actual type of the object instance that x points to • However, the only candidates are methods whose signature matches the object reference type of y • These are the ones with a formal parameter whose type is the same class or a subclass, but not a superclass • If none match, there is a compile-time error
Example class Date{ … public boolean equals(Date other){ return (this.year == other.year && this.month == other.month && this.day == other.day); } } Object o = new Date(2006,10,18); Date d = new Date(2006,10,18); System.out.println(d.equals(o));// no matching signature System.out.println(o.equals(d));// more subtle
Overriding a Method in a Superclass • Method in superclass is overridden ONLY if signature matches • To override the equals method in the Object class, we must specify that the explicit parameter has type Object • Then inside the method code, we must CAST this to the actual type of the object before we use it
The instanceof operator • note: not instanceOf • x instanceof y returns true if the object that x points to is an instance of class y, and false otherwise • good idea to use it inside any method such as Date that overrides the equals method of the Object class, checking whether the explicit parameter really is an instance of the right class before casting it (otherwise an error will be generated) • equals should return false if the actual parameter object is an instance of the wrong class
Now what happens? • Object o = new Date(2006,10,18); • Date d = new Date(2006,10,18); • Time t = new Date(2006,10,18,11,0,0); • o.equals(d) • d.equals(o) • o.equals(t) • t.equals(o) • etc….