NextTimePolymorphicType.java |
package lectures.interfaces; import util.annotations.WebDocuments; /** * Now we no longer differentiate between variables holding instances of the * two factorial classes. * We use a special type {FactorialSpreadsheet}, which is an * interface rather than a class. * This class illustrates why interfaces are important. */ @WebDocuments({"Lectures/Interfaces.pptx", "Lectures/Interfaces.pdf", "Videos/Interfaces.avi"}) public class NextTimePolymorphicType { /* * Go to the declaration of FactorialSpreadsheet (interface), ALoopingFactorialSpreadsheet, * and ARecursiveFactorialSpreadsheet ((Fn) F3/ (CTRL/CMD) click). * Use ALT <- in each of these types to return here. * Note the aspects common to both * ALoopingFactorialSpreadsheet and ARecursiveFactorialSpreadsheet captured by * the interface FactorialSpreadsheet. * * * An interface declares: * method headers and bodies that appear in all classes that implement it. * method headers that appear in all classes that implement it. * method bodies that that appear in all classes that implement it. * * (T/F) An interface provides a Java type to unite classes that implement the * same conceptual type */ /* * Below the interface is used as the type of variables. */ static FactorialSpreadsheet a = new ALoopingFactorialSpreadsheet(); static FactorialSpreadsheet b = new ARecursiveFactorialSpreadsheet(); /* * (T/F If class C implements interface I, then an instance of C can be * assigned to a variable of type I. */ /* * Uncomment the statement below and note any compile errors you get. * Comment it back to remove any errors */ // static ARecursiveFactorialSpreadsheet d = new ALoopingFactorialSpreadsheet(); /* * (T/F) If classes C1 and C2 implement an interface I, then an instance of C1 * can be assigned to a variable of type C2. */ /* * Let us try to better understand what the implements clause really means. * Uncomment the method, public int getA(), in the interface, which does * not appear in the classes. * Do you get a compile error in the two classes * (ALoopingFactorialSpreadsheet or ARecursivefactoralSpreadsheet) * that implement it? If so, what does it say? * Comment getA() out if you do. * * Now go to {ALoopingFactorialSpreadsheet) * Uncomment getN(), which does not appear in the interface. * Do you get an error message? If so, what does it say. * Comment getN() out if you do, otherwise keep it. * * (T/F) If class C implements I, then C must have a method matching * every method in I. * (T/F) If class C implements I, then I must have a method matching * every method in C. */ /* * Comment out the following statements. Notice any compile errors? * (a is assigned an instance of ALoopingFactorialSpreadsheet; * */ public static void casting() { // System.out.println (a.getN()); // System.out.println (((ALoopingFactorialSpreadsheet) a).getN()); } /* * Given an arbitrary class C that implements I and given an uncast variable v of type * I: * (a) all methods implemented by C can be invoked on v. * (b) methods declared in I can be invoked on v. * (c) no method implemented by C can be invoked on v. * * (T/F) Casting can be used to change the set of methods that can be invoked on an Object value */ /** * Run this method when asked. */ public static void main (String[] args) { System.out.println ("Before the call to maybeAssignToA a is assigned an instance of:" + a.getClass().getSimpleName()); maybeAssignToA(); System.out.println ("After the call to maybeAssignToA a is assigned an instance of:" + a.getClass().getSimpleName()); // callPrints(); // printInstanceOf(); } /* * Run the main a few times (at least 5) to look at the outputs. */ public static void maybeAssignToA() { /* * There is a 50/50 chance, when the program is executed, that the * condition of the following if will be satisfied. */ if (Math.random() > 0.5) { // hover on random to see what it does a = b; } } /* * In class PolymoprhicType, before the call to maybeAssignToA(), the * class of the object assigned to a is: * (a) always ALoopingFactorialSpreadsheet. * (b) always ARecursiveFactorialSpreadsheet. * (c) sometimes ALoopingFactorialSpreadsheet and sometimes ARecursiveFactorialSpreadsheet. * (d) None of the above. * * At the end of the call to maybeAssignToA() the class of the object assigned to a is: * (a) always ALoopingFactorialSpreadsheet. * (b) always ARecursiveFactorialSpreadsheet. * (c) sometimes ALoopingFactorialSpreadsheet and sometimes ARecursiveFactorialSpreadsheet. * (d) None of the above. * * (T/F) A compiler analysis of the source code of any class can always determine * the class of the object assigned to any variable after a procedure call * or some other statement of the program. * * Given the variable declaration: * I v = new C(); * the operations that are allowed on v by the compiler should depend on: * (a) I * (b) C * * A polymorphic variable is one that can be assigned instances of different * classes. * * (T/F) In PolymorphicType, the variable, a, is polymorphic. * * Comment out the call to the above method in main to unclutter the output. */ /* * Uncomment the call to the following method in main and run main again and view the * output. */ public static void printInstanceOf () { System.out.println (a instanceof ALoopingFactorialSpreadsheet); System.out.println (a instanceof FactorialSpreadsheet); System.out.println (a instanceof ARecursiveFactorialSpreadsheet); System.out.println (b instanceof FactorialSpreadsheet); } /* * You can click F3 or CTRL/COMMAND Click on the name of variables a and b to see their * declarations and use ALT <- to return here. * * If C1 and C2 implements I then: * (a) all instances of C1 are also instances of I. * (b) all instances of I are also instances of C1. * (c) all instances of C1 are also instances of C2. * * Click on the name FactorialSpreadsheet and press F4, Fn F4 or * Right Menu-> Open Type Hierarchy * * In the type hierarchy: * (a) ALoopingFactorialSpreadsheet is a child of FactorialSpreadsheet. * (b) ARecursiveFactorialSpreadsheet is a child of ALoopingFactorialSpreadsheet. * (c) FactorialSpreadsheet is a child of ALoopingFactorialSpreadsheet. * * In the type hierarchy, if TC is a child of TP, then all instances of: * TC are also instances of TP. * TP are also instances of TC. * None of the above. * * Comment out the call to the method in main to unclutter the output. */ /* * Study the definition of printPolymorphic. */ public static void printPolymorphic (FactorialSpreadsheet aFactorialSpreadsheet) { System.out.println (aFactorialSpreadsheet.getNumber() + ":" + aFactorialSpreadsheet.getFactorial()); } /* * (T/F) The type of the formal parameter of printPolymorphic is an interface. */ /* * Now study the definition of printNonPolymoprhic. */ public static void printNonPolymoprhic (ALoopingFactorialSpreadsheet aFactorialSpreadsheet) { System.out.println (aFactorialSpreadsheet.getNumber() + ":" + aFactorialSpreadsheet.getFactorial()); } /* * (T/F) The type of the formal parameter of printNonPolymoprhic is an interface. */ public static void callPrints() { ALoopingFactorialSpreadsheet l = new ALoopingFactorialSpreadsheet(); ARecursiveFactorialSpreadsheet r = new ARecursiveFactorialSpreadsheet(); /* * Uncomment the statements below and note the error messages. * Do the error messages make sense. */ // printPolymorphic(l); // printPolymorphic(r); // printPolymorphic(a); // printPolymorphic(b); // // printNonPolymoprhic(l); // printNonPolymoprhic(r); // printNonPolymoprhic(a); // printNonPolymoprhic(b); } /* * In PolymorphicType, the formal parameter of printPolymorphic can be * assigned an actual parameter of type * a) ALoopingFactorialSpreadsheet. * b) ARecursiveFactorialSpreadsheet. * c) FactorialSpreadsheet * * In PolymorphicType, the formal parameter of printNonPolymorphic can be * assigned an actual parameter of type: * a) ALoopingFactorialSpreadsheet. * b) ARecursiveFactorialSpreadsheet. * c) FactorialSpreadsheet * *(T/F) If class C implements interface I, then a variable of type I can be assigned a variable of type C. *(T/F) If class C implements interface I, then a variable of type C can be assigned a variable of type I. * A polymorphic method is one that declares at least parameter that * is a polymorphic variable. * * (T/F) A polymorphic method has one or more (formal) parameters that can be * assigned instances of multiple classes. * * Which print is more versatile, that is, can operate on a greater * variety of objects? * * (T/F) printPolymorphic is more reusable, that is can be used in more contexts, * than printNonPolyMoprhic. * * A parameter is an example of a variable. * * (T/F) If class C implements I, then C should be used as the type of a variable. * * Interfaces * (a) make code more reusable * (b) constrain or specify the nature of classes that implement them. * (c) provide an abstract description of the classes that implement them. * (d) none of the above. * (T/F) Every class (with one or more instance methods) should implement an interface. * */ }