JMU
Lab: Experimenting with Polymorphism through Inheritance


Instructions:Omitted

Getting Ready:Omitted

1. Finding Errors Related to Polymorphism: This part of the lab will help you learn how to find errors related to polymorphism.
  1. Familiarize yourself with the Document and FormattedDocument classes. (Note: These classes are different from any earlier versions you may have seen or used.)
  2. Compile all of the classes
  3. Execute Driver1.
  4. What output was generated?
    This document has 18 words and 2 lines
    
    George is a little monkey, and all monkeys are curious.
    But no monkey is as curious as George.
    
  5. Is the output correct?
    Yes.
  6. Execute Driver2.
  7. What output was generated?
    This document has 18 words and 2 lines
    
    George is a little
    monkey, and all
    monkeys are
    curious.
    But no
    monkey is as curious
    as George.
    
  8. What is wrong with the output?
    The line count is not consistent with the output.
  9. Why is the output incorrect? (Hint: Use a debugger or add output statements to the getLineCount() method.)
    The getLineCount() method uses the text attribute directly rather than calling the getText() method.
2. Review of Accessibility/Visibility: This part of the lab reviews some issues involving accessibility/visibility.
  1. Make the attribute text in the Document class private.
  2. Compile the Document and FormattedDocument classes (in that order).
  3. What compile-time errors are generated and why?
    FormattedDocument.java:50: text has private access in Document
            tokenizer = new StringTokenizer(text, " ");
                                            ^
    
  4. Fix the problem (without changing the accessibility/visibility of text). (Hint: How can a FormattedDocument object get access to text if it's private?)
  5. What did you do to fix the problem?
    Used the getText() method rather than the text attribute. That is:
    	tokenizer = new StringTokenizer(super.getText(), " ");
    
  6. Compile and execute Driver2. (Note: You should not get a runtime exception. If you do, you made a mistake when you answered the previous question that resulted in an infinite recursion - a method calling itself forever. You should be able to figure it out; if not, ask for help before proceeding.)
  7. What output is generated?
    This document has 18 words and 2 lines
    
    George is a little
    monkey, and all
    monkeys are
    curious.
    But no
    monkey is as curious
    as George.
    
  8. Is the output correct?
    No.
3. Polymorphism Basics: This part of the lab will help you gain a better understanding of the basics of polymorphism through inheritance.
  1. In Driver2, the getDescription() message is sent to the object named formatted. What code is executed as a result (i.e., what class is the code in)?
    The code in the Document class. (Note: The getDescription() method is inherited.)
  2. Continuing with this same example, the getDescription() method sends the message getLineCount() to this. What code is executed as a result? Why?
    this refers to the object named formatted in Driver2. Hence, the FormattedDocument class is searched first. But, since the FormattedDocument class does not have an explicit getLineCount() method, the parent class is searched (for an inherited method). There is such a method in the Document class so the code in that class is executed.
4. The Complexities of Polymorphism: This part of the lab will help you gain a better understanding of the complexities that arise because of polymorphism.
  1. Change the getLineCount() method in the Document to the following:
    getLineCount.java
    
    
  2. Explain the changes.
    The new version uses the getText() method (and a local variable) rather than the text attribute.
  3. In Driver2, the getText() message is sent to the object named formatted. What code is executed as a result? Why?
    The code in the FormattedDocument class (because the method in the FormattedDocument class overrides the method in the Document class).
  4. In Driver2, the getDescription() message is sent to the object named formatted. What code is executed as a result (i.e., what class is the code in)?
    As before, the code in the Document class.
  5. Continuing with this same example, the getDescription() method sends the message getLineCount() to this. What code is executed?
    this refers to the object named formatted in Driver2. Hence, the FormattedDocument class is searched first. But the FormattedDocument class does not have an explicit getLineCount() method. Hence, the parent class is searched (for an inherited method). There is such a method in the Document class so the code in the Document class is executed.
  6. Continuing with this example, the new version of getLineCount() sends the getText() message to this. What code is executed as a result? Why?
    This one is a little tricky. Remember (from the discussion of the answer to the previous question) that the getLineCount() message is sent to the object named formatted in Driver2 which means that this refers to formatted. Hence, the FormattedDocument class is searched first. There is a getText() method in the FormattedDocument class (it overrides the version in the Document class) so the code in the FormattedDocument class is executed.
  7. Compile and execute Driver2.
  8. What output is generated?
    This document has 18 words and 7 lines
    
    George is a little
    monkey, and all
    monkeys are
    curious.
    But no
    monkey is as curious
    as George.
    
  9. Is the output correct?
    Yes.
  10. Compile and execute Driver1.
  11. What output is generated?
    This document has 18 words and 2 lines
    
    George is a little monkey, and all monkeys are curious.
    But no monkey is as curious as George.
    
  12. Is the output correct?
    Yes.
5. Polymorphism, Overloading and Parameters: This part of the lab will help you gain a better understanding of passing polymorphic objects to overloaded methods.
  1. Open and read Driver3.
  2. What overloaded methods are in Driver3?
    It contains two print() methods, one that is passed a Document and one that is passed a FormattedDocument.
  3. Compile and execute Driver3.
  4. What output was generated?
    A nicely formatted document:
    
    George is a little
    monkey, and all
    monkeys are
    curious.
    But no
    monkey is as curious
    as George.
    
  5. Which print() method was executed?
    The one that is passed a FormattedDocument.
  6. Why was that print() method executed?
    When the compiler got to the call to print() in main(), it needed to look for a print() method that can be passed the object named formatted. Since formatted is declared to be a FormattedDocument object it found two, one that is passed a Document and one that is passed a FormattedDocument. Both are appropriate because formatted is polymorphic (i.e., it is both a Document and a FormattedDocument. The compiler chooses the most specialized/specific version which, in this case, is the version that is passed a FormattedDocument.
  7. In Driver3, comment-out the print() method that is passed a FormattedDocument.
  8. Review: Should Driver3 compile? Why or why not?
    It should compile because a FormattedDocument "is a" Document (i.e., FormattedDocument specializes Document).
  9. Compile and execute Driver3.
  10. What output was generated?
    A document:
    
    George is a little
    monkey, and all
    monkeys are
    curious.
    But no
    monkey is as curious
    as George.
    
  11. Which print() method was executed?
    The one that is passed a Document.
  12. Why was that print() method executed?
    There is only one print() method.
  13. Remove the comments around the commented-out print() method that is passed a FormattedDocument. (That is, make sure Driver3 again has both print() methods.)
  14. In Driver3, modify the declaration of formatted so that it is now a Document.
  15. What is the declaration now?
    Document        formatted;
    
  16. Review: Should Driver3 compile? Why or why not?
    It should compile because a FormattedDocument "is a" Document (i.e., FormattedDocument specializes Document).
  17. Execute Driver3.
  18. What output was generated?
    A document:
    
    George is a little
    monkey, and all
    monkeys are
    curious.
    But no
    monkey is as curious
    as George.
    
  19. Which print() method was executed?
    The one that is passed a Document.
  20. Why was that print() method executed?
    When the compiler got to the call to print() in main(), it needed to look for a print() method that can be passed the object named formatted. Since formatted is declared to be a Document object it found only one, the one that is passed a Document.

    Even though, at run time, formatted will actually be a FormattedDocument object, the compiler can't always know that. So, it uses the declared type.

  21. Why is the text formatted?
    The getText() message is sent to the object named doc at run-time. At run time, the doc object is a FormattedDocument. So, the FormattedDocument class is searched first.
  22. Without making any other changes in Driver3, comment-out the print() method that is passed a Document.
  23. Compile Driver3.
  24. What error is generated?
    Driver3.java:25: print(FormattedDocument) in Driver3 cannot be applied to (Docum
    ent)
            print(formatted);
            ^
    1 error
    
  25. Why is this error generated?
    When the compiler got to the call to print() in main(), it needed to look for a print() method that can be passed the object named formatted. Since formatted is declared to be a Document object it didn't find one.

Copyright 2011