Java Reference
In-Depth Information
The compiler produces four errors: one error for each line that tries to access an
inherited private field, and a message about a missing
Stock()
constructor:
DividendStock.java:5: cannot find symbol
symbol : constructor Stock()
location: class Stock
public DividendStock(String symbol) {
∧
DividendStock.java:6: symbol has private access in Stock
DividendStock.java:7: totalShares has private access in Stock
DividendStock.java:8: totalCost has private access in Stock
The first problem is that even though a
DividendStock
does contain the
symbol
,
totalShares
, and
totalCost
fields by inheritance, it cannot refer to them directly
because they were declared private in the
Stock
class.
The second problem—the missing
Stock()
constructor—is a subtle and confus-
ing detail of inheritance. A subclass's constructor must always begin by calling a
constructor from the superclass. The reason is that a
DividendStock
object partially
consists of a
Stock
object, and you must initialize the state of that
Stock
object first
by calling a constructor for it. If you don't do so explicitly, the compiler assumes that
Stock
has a parameterless
Stock()
constructor and tries to initialize the
Stock
data
by calling this constructor. Since the
Stock
class doesn't actually have a parameter-
less constructor, the compiler prints a bizarre error message about a missing
Stock()
constructor. (It's a shame that the error message isn't more informative.)
The solution to this problem is to explicitly call the
Stock
constructor that accepts
a
String
symbol as its parameter. Java uses the keyword
super
for a subclass to
refer to behavior from its superclass. To call a constructor of a superclass, write the
keyword
super
, followed by the constructor's parameter values in parentheses:
super(<expression>, <expression>, ..., <expression>);
In the case of the
DividendStock
constructor, the following code does the trick.
Use the
super
keyword to call the superclass constructor, passing it the same
symbol
value that was passed to the
DividendStock
constructor. This action will
initialize the
symbol
,
totalShares
, and
totalCost
fields. Then set the initial
dividends to
0.0
:
// constructs a new dividend stock with the given symbol
// and no shares purchased
public DividendStock(String symbol) {
super(symbol); // call Stock constructor
dividends = 0.0;
}
Search WWH ::
Custom Search