| PolymorphicType.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 PolymorphicType {
/*
* 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 C1.
*/
/*
* 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.
* 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 should implement an interface. *
*/
}