5 Steps to a 5 AP Computer Science A 2017 (2016)

STEP 4

Review the Knowledge You Need to Score High

CONCEPT 8

Inheritance and Polymorphism

IN THIS CONCEPT

Summary: In order to take advantage of everything an object-oriented language has to offer, you must learn about its ability to handle inheritance. This concept explains how superclasses and subclasses are related within a class hierarchy. It also explains what polymorphism is and how objects within a class hierarchy may act independently of each other.

Key Ideas

   A class hierarchy describes the relationship between classes.

   Inheritance allows objects to use features that are not defined in their own class.

   A subclass extends a superclass (a child class extends a parent class).

   Child classes do not have direct access to their parent’s private instance variables.

   A child class can override the parent class methods by simply redefining the method.

   Polymorphism is what happens when objects from child classes are allowed to act in a different way than objects from their parent classes.

   The Object class is the parent of all classes (the mother of all classes).

Inheritance

Sorry, this inheritance is not about a large sum of money that your crazy, rich uncle has left you. It is, however, a feature of Java that is immensely valuable. It allows objects from one class to inherit the features of another class.

Class Hierarchy

One of the most powerful features of Java is the ability to create a class hierarchy . A hierarchy allows a class to inherit the attributes of another class, making the code reusable . This means that the classes on the lower end of the hierarchy inherit features (like methods and instance variables) without having to define them in their own class.

In biology, animals are ranked with classifications such as species, genus, family, class, kingdom, and so on. Any given rank inherits the traits and features from the rank above it.

Example

Demonstrate the hierarchy of cats, dogs, horses, and elephants. Note that all German shepherds are dogs, and all dogs are mammals, so all German shepherds are mammals.

Parent Versus Child Classes (Superclass Versus Subclass)

So what does this have to do with computer programming? Well, in Java, a class has the ability to extend another class. That is, a child class (subclass ) has the ability to extend a parent class (superclass ). When a child class extends a parent class, it inherits the instance variables and methods of the parent class. This means that even though the child class doesn’t define these instance variables or methods on its own, it has them. This is a powerful way to reuse code without having to rewrite it.

Note: The methods from a parent class are inherited and can be used by the child class. However, the child class gets its own set of instance variables that are separate from the parent class. The instance variables for the parent and the instance variables for the child are two different sets of instance variables. The child class can only access the private instance variables of the parent by using the accessor and mutator methods from the parent class.

Something for Nothing

Child classes inherit the methods of their parent class. This means that the child objects automatically get these methods without having to define them for themselves.

The Keyword extends

The words superclass and parent are interchangeable as are subclass and child . We say, “a child class extends a parent class” or “a subclass is derived from a superclass.” The phrase is-a refers to class hierarchy. So when we refer to classes such as Dog or Mammal, we say “a Dog is-a Mammal” or even “a GermanShepherd is-a Mammal.”

A class can extend at most one other class ; however, there is no limit to how many classes can exist in a class hierarchy.

The Keyword extends

The keyword extends is used to identify that inheritance is taking place. A child class can only extend one parent class.

Example

Simulate class hierarchy and inheritance using the Mammal hierarchy. Each subclass inherits the traits of its superclass and can add additional traits of its own.

Be Your Own Class

Child classes are allowed to define additional methods of their own. The total number of methods that the child class has is a combination of both the parent class and child class methods.

The Keyword super

When you make an object from a child class, the child class constructor automatically calls the no-argument constructor of the parent class using the super() call (some integrated development environments, or IDEs, display this instruction). However, if you want to call a parent constructor with arguments from the child class constructor, you need to put that in your code explicitly as the first line of code in the child class constructor using the super(arguments) instruction. The child is then making a call to a parameterized constructor of the parent class.

Example

Demonstrate a child class that has two constructors. The no-parameter constructor makes a call to the parent’s no-parameter constructor. The parameterized constructor makes a call to the parent’s parameterized constructor. Note: The super() call must be the first line of code in each of the child’s constructors.

Data Encapsulation Within Class Hierarchy

A subclass can only access or modify the private instance variables of its parent class by using the accessor and modifier methods of the parent class.

Children Don’t Have Direct Access to Their Parent’s private Instance Variables

Parent and child classes may both contain instance variables. These instance variables should be declared private. This is data encapsulation. Children have to use the accessor and modifier methods of the parent class to access their parent’s private instance variables.

Polymorphism

“Sometimes children want to act in a different way from their parents.”

Overriding a Method of the Parent Class

In Java, a child class is allowed to override a method of a parent class. This means that even though the child inherited a certain way to do something from its parent, it can do it in a different way if it wants to. This is an example of polymorphism .

The way to make a child override a parent method is to redefine a method (the signature must be exactly the same) and change what is done in the method. When an object from the child class calls the method, it will perform the action that is found in the child class rather than the method of the parent class.

Example

All objects from the FamilyMember class drink from a cup and eat with a fork. However, objects from the Baby class drink from a cup and eat with their hands. All objects from the SporkUser class drink from a cup and eat with a spork. In this case, the eat method of the FamilyMember class is overridden by both the Baby class and the SporkUser class. Therefore, even though the name of the method is the same, the objects from Baby class and SporkUser class eat in a different way than objects from the FamilyMember class. The decision of when to use the overridden method by all objects that extend a superclass is made when the program is compiled and this process is called static binding .

Polymorphism

Java uses the term polymorphism to describe how different child classes of the same parent class can act differently. This is accomplished by having the child class override the methods of the parent class.

Dynamic Binding

A problem arises when we want to make a list of family members. To make an array or ArrayList of people in the family, they all have to be of the same type! To solve this problem, we make the reference variables all of the parenttype.

Example

Create a FamilyMember ArrayList to demonstrate dynamic binding. Make the reference variables all the same type (the name of the parent class) and make the objects from the child classes. Allow each object to eat and drink the way they were designed to eat and drink. The decision of how each FamilyMember object eats is decided while the program is running (known as run-time ) and this process is called dynamic binding . It’s pretty cool!

Reference Variables and Hierarchy

The reference variable can be the parent of a child object.

The reference variable cannot be a child of a parent object.

Using super from a Child Method

Even if a child class overrides a method from the parent class, an object from a child class can call its parent’s method if it wants to; however, it must do it from the overriding method. By using the keyword super , a child can make a call to the parent method that it has already overridden. We say, “The child can invoke the parent’s method if it wants to.”

Example

Revise the Baby class so that if a baby is older than three years, it eats with either its hands or a fork; otherwise it eats with its hands. Use the keyword super to make a call to the parent’s eat method. Also, add an instance variable for the age.

Beware When Using a Parent Reference Variable for a Child Object

A child object has the ability to perform all the public methods of its parent class. However, a parent does not have the ability to do what the child does if the child action is original. Also, if a child object has a parent reference variable, the child does not have the ability to perform any of the unique methods that are defined in its own class.

Example

Demonstrate that a parent reference variable cannot perform any of the methods that are unique to a child class. A FamilyMember object does not know how to throwTantrum. Only a Baby object knows how to throwTantrum. Note: Even though babyCousin is a Baby object, the FamilyMember reference variable prevents it from being able to throwTantrum.

Downcasting

The problem described in the previous example can be solved using a technique called downcasting . This is similar to—but not exactly the same as—casting an int to a double. A parent object reference variable is cast to the object type of the object that it references.

Downcasting

You can downcast a parent reference variable to a child object as long as the object it is referring to is that child.

Example 1

Demonstrate downcasting by allowing the parent reference variable to perform a method that is unique to a child class. The parent reference variable is cast as a child and must refer to the child object. Pay close attention to the parentheses when casting.

Example 2

You are not allowed to cast a parent reference object to a child if the object is a parent. In this example, mom is a FamilyMember reference variable that refers to a FamilyMember object. Attempting to cast mom as a Baby results in an error.

The Object Class

The Object class is the mother of all classes. Every class, even the ones you write, is a descendent of the Object class. The extends is implied , so you don’t have to write, “extends Object”, in your own classes. The Object class does not have any instance variables, but it does have several methods that every descendent inherits. Two of these methods, the toString and the equals , are tested on the AP Computer Science A Exam. You must be able to implement the toString method; however, you only need to know how to use the equals method (like we do when we compare String objects).

Overriding the toString Method

The toString method is inherited from the Object class and was created to describe the object in some way, typically by referencing its instance variables. The Object class’s toString method doesn’t give you anything valuable (it returns the hex value of the object’s address). Most of the time, when creating your own classes, you will override the toString method so it returns a String that describes the object in a meaningful way.

Example

Override the toString method for the Circle class (used in Concept 2) so the method gives a description of the Circle object that calls it. The String that is returned should include the radius of the circle.

Overriding the toString Method

All classes extend the Object class. When you design your own classes, be sure to override the toString() method of the Object class so that it describes objects from your class in a unique way using its own instance variables.

Casting an Object

If a method’s parameter list contains an Object reference variable, then you will have to downcast the reference before using it. You must make sure that the object that you are casting is-a object from the class.

Example

Demonstrate how to handle an Object reference parameter. In this example, when the FamilyMember object, uncleDon, gets passed to the timeToEat method, he is sent as a FamilyMember reference variable. When he is received by the timeToEat method, he is renamed as hungryMember and is now an Object reference. Finally, he is cast to a FamilyMember and is then able to eat.

 Rapid Review

Hierarchy and Inheritance

  • One major advantage of an object-oriented language is the ability to create a hierarchy of classes that allows objects from one class to inherit the features from another class.
  • A class hierarchy is formed when one class extends another class.
  • A class that extends another class is called the child or subclass.
  • The class that is extended is called the parent or superclass.
  • A class can only extend one other class.
  • A class hierarchy can extend as many times as you want. That is, a child can extend a parent, then the parent can extend another parent, and so on.
  • When a class hierarchy gets extended to more than just one parent and one child, the lower ends of the hierarchy inherit the features of each of the parent classes above it.
  • The phrase “is-a” helps describe what parent classes a child class belongs to.
  • If you want a child class to modify a parent class’s method, then you override the parent class’s method. To do this, you simply redefine the method in the child class (using the exact same method declaration and replace the code with what you want the child to do).
  • The word “super” can be used to refer to either a parent’s constructor or methods.
  • To purposefully call the no-argument super constructor, you must put super() as the first line of code in the child’s constructor. Other instructions are placed after the super() call.
  • To call the parameterized super constructor, you must put super(arguments) as the first line of code in the child’s parameterized constructor. Other instructions are placed after the super() call.
  • If you write a method that overrides the parent class’s method, you can still call the original parent’s method if you want to. Example: super.parentMethod();
  • A reference variable can be a parent class type if the object being created is its child class type.
  • A reference variable cannot be a child class type if the object being created is its parent class type.
  • A reference variable that is of a parent data type can be cast to a child data type as long as the object that it is referencing is a child object of that type.

Polymorphism

  • Polymorphism is when more than one child class extends the same parent class and each child object is allowed to act in a different way than its parent and even its siblings.
  • If several child classes extend the same parent class and each child class overrides the same method of the parent class in its own unique way, then each child will act differently for that method.
  • Static binding is the process of deciding which method the child reference variable will perform during compile-time.
  • Dynamic binding is the process of deciding which method the parent reference will perform during run-time.
  • The Object class is the mother of all classes in Java since it is the root of the class hierarchy and every class has Object as a superclass.
  • The Object class contains two methods that are tested on the AP exam: equals and toString.
  • The public boolean equals(Object other) method returns true if the object reference variable that calls it is referencing the same exact object as other. It returns false if the object reference variables are not referencing the same object.
  • It is common to override the equals method when you want to determine if two objects from a class are the same.
  • The public String toString() method returns a String representation of the object.
  • It is very common to override the toString() method when generating your own classes.
  • Downcasting is casting a reference variable of a parent class to one of its child classes.
  • Downcasting is commonly used when an Object is in a parameter list or ArrayList.
  • A major problem with downcasting is that the compiler will not catch any errors, and if the cast is made incorrectly, a run-time error will be thrown.

 Review Questions

Basic Level

  1. Assuming all classes are defined in a manner appropriate to their names, which of the following statements will cause a compile-time error?

(A)   Object obj = new Lunch();

(B)   Lunch lunch = new Lunch();

(C)   Lunch sandwich = new Sandwich();

(D)   Lunch lunch = new Object();

(E)   Sandwich sandwich = new Sandwich();

Questions 2–4 refer to the following classes.

  1. Which of the following is true with respect to the classes defined above?
  2. Freshmanis a subclass of UnderClassman and UnderClassman is a subclass of Student
  3. Studentis a superclass of both UnderClassman and Freshman

III.   UnderClassman is a superclass of Freshman and a subclass of Student

(A)   I only

(B)   II only

(C)   I and II only

(D)   II and III only

(E)   I, II, and III

  1. Which of the following lists of instance data contains only variables that are directly accessible to aFreshman class object?

(A)   middleSchoolCode, homeRoomNum, gpa, gradYear

(B)   middleSchoolCode, counselor, homeRoomNum

(C)   homeRoomNum, counselor, gradYear

(D)   middleSchoolCode, counselor, gpa

(E)   middleSchoolCode, homeRoomNum, gradYear

  1. Assume that all three classes contain parameterized constructors with the following declarations and that all variables are logically named.

Which of the following calls to super would appear in the constructor for the Freshman class?

(A)   super(gradYear, gpa, homeRoomNum, counselor, middleSchoolCode);

(B)   super(gradYear, gpa, homeRoomNum, counselor);

(C)   super(homeRoomNum, counselor);

(D)   super(gradYear, gpa);

(E)   super();

  1. Consider the following method in theStudent class.

A Freshman object must attendClass like a Student object, but also have the teacher initial his/her homework planner (using the initialPlanner method, not shown).

Which of the following shows a possible implementation of the Freshman attendClass method?

(A)   

(B)   

(C)   

(D)   

(E)   

Advanced Level

Questions 6–7 refer to the following classes.

Assume ArrayList<String> members_1 and ArrayList<String> members_2 have been properly instantiated and initialized with a non-zero number of appropriate elements.

  1. Which of the following declarations is NOT valid?

(A)   Club[] clubs = new SchoolClub[7];

(B)   Club[] clubs = {new Club(members_1), new Club()};

(C)   SchoolClub[] clubs = {new SchoolClub("Mr. Johnson", members_1),
new Club(members_2)};

(D)   SchoolClub[] clubs = {new SchoolClub("Ms. Paymer", members_1),
new SchoolClub("Mr. Johnson", members_2)};

(E)   All of the above are valid.

  1. Which of the following could replace/* missing code */ in the SchoolClub constructor to ensure that all instance variables are initialized correctly?

(A)   super(theMembers);

advisor = theAdvisor;

(B)   super(new Club(theMembers));

advisor = theAdvisor;

(C)   this.SchoolClub = new Club(members);

advisor = theAdvisor;

(D)   advisor = theAdvisor;

(E)   advisor = theAdvisor;

super(theMembers);

Questions 8–9 refer to the following classes.

  1. Consider the following code segment.

What is printed as a result of executing the code segment?

(A)   contains kazoo

(B)   kazoo

(C)   contains kazoo for a child age 4

(D)   Nothing is printed. Compile-time error: illegal cast

(E)   Nothing is printed. Run-time error: illegal cast

  1. Consider the following code segment.

What is printed as a result of executing the code segment?

(A)   contains blocks

(B)   contains blocks for a child age 4

(C)   contains kazoo for a child age 4

(D)   Nothing is printed. Compile-time error: there is no setContents method in the KidsPresent class

(E)   Nothing is printed. Run-time error: there is no setContents method in the KidsPresent class

  1. Free-Response Practice: Point3D Class

Consider the following class:

Write the class Point3D that extends this class to represent a three-dimensional point with x, y, and z coordinates. Be sure to use appropriate inheritance. Do not duplicate code.

You will need to write:

  • A constructor that takes three int values representing the x, y, and z coordinates
  • Appropriate mutator and accessor methods (setters and getters)

 Answers and Explanations

Bullets mark each step in the process of arriving at the correct solution.

  1. The answer is D.
  • When you instantiate an object, you tell the compiler what type it is (left side of the equal sign) and then you call the constructor for a specific type (right side of the equal sign). Here’s where you can putis-a to good use. You can construct an object as long as it is-a version of the type you have declared. You can say, “Make me a sandwich, and I’ll say thanks for lunch,” and you will always be right, but you can’t say, “Make me lunch and I’ll say thanks for the sandwich.” What if I made soup?
  • Option A is correct, since Lunchis-a Object.
  • Options B and E are correct since Lunchis-a Lunch, and Sandwich is-a Sandwich. (Don’t confuse the variable name sandwich with the type Lunch. It’s a bad programming choice, since a reader expects that a variable named sandwich is an object of the class Sandwich, but it’s legal.)
  • Option C is correct since Sandwichis-a Lunch.
  • Option D is incorrect. Object is not a Lunch. It’s not reversible. The one on the right has to have anis-a relationship to the one on the left in that order. Option D will not compile.
  1. The answer is E.
  • Superclass refers to grandparents as well as parents, all the way up the inheritance line, and subclass refers to grandchildren as well as children, all the way down the inheritance line, so all three relationships are true.
  1. The answer is E.
  • A Freshman object will have direct access to its own public and private variables, and the public variables of its superclasses.
  • Please note that it is considered a violation of encapsulation to declare instance variables public, and points may be taken off on the AP exam if you do so!
  1. The answer is B.
  • Since the super call must be the first thing in the constructor, the Freshman constructor will hang on to the parameter middleSchoolCode and use the super call to pass the remaining parameters to the constructor for Underclassman. It will then set its own instance variable to the middleSchoolCode parameter. (It’s worth noting that the Underclassman constructor will set its own two variables and pass the remaining variables to its super constructor.)
  1. The answer is D.
  • Options A and B are incorrect. They show an incorrect usage of “extends". The keyword extends belongs on the class declaration, not the method declaration.
  • Option C is incorrect. It puts data types next to the arguments (actual parameters) in the super method call. Types only appear next to the formal parameters in the method declaration.
  • Option D is correct. It has fixed both of the above errors. The method with the same name in the superclass is called using the super.methodName notation, and it is passed the two parameters it is expecting. Then the initialPlanner method is called.
  • Option E is incorrect. It attempts to assign the parameters directly to their corresponding variables in the Student class. The variables in the parent class should be private, so the child doesn’t know if they exist, and can’t access them even if they do. Also, the child class shouldn’t assume that assigning variables is all the parent class method does. Surely attendClass involves more than that!
  1. The answer is C.
  • Option A is valid. It instantiates an array of Club objects. The right side of the instantiation specifies that there will be two entries, but it does not instantiate those entries. This is a valid statement, but note that the entries in this array are null.
  • Option B is valid. It uses an initialization list to instantiate the array of Club objects. Club has overloaded constructors. There is a constructor that takes an ArrayList<String> as an argument, so the first entry is correct, and there is a no-argument constructor, so the second entry is correct.
  • Option C is not valid. It uses an initialization list to instantiate an array of SchoolClub objects, but the list includes not only a SchoolClub object, but also a Club object. We could make a Club[] and include SchoolClub objects, but not the other way around. Remember theis-a designation. A Club is not a SchoolClub.
  • Option D is valid. It instantiates an array of SchoolClub objects by giving an initialization list of correctly instantiated SchoolClub objects.
  1. The answer is A.
  • The first statement in the constructor of an extended class is a super call to the constructor of the parent class. This may be an implicit call to the no-argument constructor (not explicitly written by you) or it may be an explicit call to any of the superclass’s constructors.
  • Option B is incorrect. It calls the super constructor but passes a parameter of the wrong type.
  • Option C is incorrect. this.SchoolClub has no meaning.
  • Option D is incorrect. This option is syntactically correct. The no-argument constructor will be called implicitly, but the members ArrayList instance variable will not be set.
  • Option E is incorrect. The super call must be the first statement in the constructor.
  1. The answer is C.
  • First of all, remember that when an object is printed, Java looks for that object’s toString method to find out how to print the object. (If there is no toString method, the memory address of the object is printed, which is not what you want!)
  • Variable p is of type Present. That’s what the compiler knows. But when we instantiate variable p, we make is a KidsPresent. That’s what the runtime environment knows. So when the runtime environment looks for a toString method, it looks in the KidsPresent class. The KidsPresent toString prints both the contents and the appropriate age.
  1. The answer is B.
  • Since p is declared as a Present, and the Present class has a setContents method, the compiler is fine with this sequence.
  • When setContents is called, the run-time environment will look first in the KidsPresent class and it will not find a setContents method. But it doesn’t give up! Next it looks in the parent class, which is Present and there it is. So the run-time environment happily uses the Present class’s setContents method and successfully sets the Present class’s contents variable to “blocks".
  • When the KidsPresent toString is called, the first thing it does is call super.toString(), which accesses the value of the contents variable. Since that variable now equals “blocks", the code segment works as you might hope it would and prints “contains blocks for a child age 4".
  1. On the AP exam, you are often asked to extend a class, as you were in this question. Check your answer against my version below. A few things to notice:
  • The constructor takes x, y, and z but then immediately passes x and y to the Point class constructor through the super(x, y) call.
  • x and y, their setters and getters are in the Point class; they don’t need to be duplicated here. Only variable z, setZ and getZ need to be added.