The first assignment statement for item1 is no surprise; it assigns an Item object to an Item variable. But that second assignment statement—assigning a SaleItem object to an Item variable? How can that possibly work? What mad sorcery is this?
Remember, we’re talking about an is-a relationship. A SaleItemis anItem. That’s why it’s legal to make the assignment. That is called polymorphism—the ability to assign a child class object to a parent class variable.
Take a look at the System.out.println statements that produced that output. The first one uses Item’s toString method to print item1 with its name, SKU, and price. The second one uses SaleItem’s toString method to print item2’s name, SKU, price and discount rate.
The answer is dynamic binding. At compile time, both item1 and item2 have the Item data type. But at run time, the JVM looks at the actual object that item2 refers to and finds that it has the SaleItem data type, and it uses SaleItem’s toString method.
We want the program to go through the array and print each item’s name and price, and, if it’s a sale item, say how much the customer saves:
Rye Bread: $3.95
Tomato Soup: $1.23 - you save $0.06
Canned Lima Beans: $2.52 - you save $0.46
Frozen Pizza: $5.19 - you save $0.71
Organic Salsa: $3.79
Note that the for loop variable is an Item, because we have told the compiler that foods is an array of Item. Here’s the big question: how do we determine—at run time—if an array element is a SaleItem or an Item? We use the instanceof operator, which takes the form:
Why can’t the compiler find getDiscount? The answer is in variable food of type Item. As far as the compiler is concerned, food is an Item, and that class does not have a getDiscount method in it.
A subclass (the child class) extends a superclass (the parent class).
A subclass constructor can call the superclass constructor by invoking the super method.
If you use a super constructor, it must be the first non-comment line.
Subclass methods can invoke the superclass methods by using super.method anywhere in the subclass method body.
Polymorphism allows you to assign a subclass object to a superclass variable. For example,
At compile time, the compiler sees the superclass variable as having the superclass data type. In the preceding code, the compiler says that myItem has data type Item.
At run time, the compiler uses the actual data type of the object. When you say:
the JVM will see that myItem contains a reference to a SaleItem object and will invoke SaleItem’s toString method.
The compiler won’t let you call a method that exists only in the subclass on a superclass variable. This won’t work:
getPrice is fine; that method belongs to Item, but getDiscount belongs only to the subclass.
You can determine if a variable belongs to a class at run time by using the instanceof operator:
Once you have established that you have a variable of the subclass data type, you can convince the compiler to treat it as a subclass by using a cast:
The extra parentheses around the cast are required to get everything evaluated in the correct order.
This exercise will let you practice polymorphism and dynamic binding. Implement the Bicycle, ElectricBicycle, and CargoBicycle classes. (These are not defined in the same way as in the preceding text.) The parent Bicycle class has these attributes and methods:
This exercise will let you practice polymorphism and dynamic binding. It uses the Account, SavingsAccount, and CreditCardAccount classes you developed in Exercise A.2.2.3. Instead of creating a customer with multiple accounts, create an array of these accounts:
A SavingsAccount number 30507 with a balance of $4,500 and an APR of 1.5\%
A CreditCardAccount number 51782737 with a balance of $7,000.00, APR of 8\%, and credit limit of $1000.00
A CreditCardAccount number 629553328 with a balance of $1,500.00, an APR of 7.5\%, and a credit limit of $5,000
A CreditCardAccount number 4977201043L with a balance of -$5,000.00, an APR of 7\%, and a credit limit of $10,000 (The L after the account number lets the compiler know that the account number is a long integer.)