Page 567 - Introduction to Programming with Java: A Problem Solving Approach
P. 567
one or more non-abstract method definitions in an abstract class. Thus, classes descended from an abstract class can inherit non-abstract methods from that class and are not required to redefine those non-abstract methods.
Illegal to Use private or final with abstract
An abstract method declaration cannot be private, and the definitions of the method that appear in descendant classes cannot be private either. Why? An abstract method declaration provides a mini- mum kludge-free way for the compiler to accept a polymorphic method call. If a method is polymorphic, versions of it appear in more than one class, so at least one of the polymorphic methods is inevitably outside the class that calls it. You can’t access an outside method that’s private, and since all definitions of a polymorphic method must have identical outside-world interfaces, none of the polymorphic definitions can be private. Since the abstract declaration in the abstract ancestor class is supposed to describe correctly what the method is like to the outside world (and to the compiler), the access modifier that appears in the abstract declaration cannot be private either.
An abstract class or method cannot be final. The final modifier keeps a class from being ex- tended and keeps a method from being overridden. But an abstract class is supposed to be extended and an abstract method is supposed to be overridden, so it’s illegal to use final with abstract.
13.9 Interfaces
Java interfaces can do lots of different things, and one of those things is help implement polymorphism. But
before we get into that, we’d like to mention a couple of other uses of a Java interface.
Using Interfaces to Standardize Inter-Class Communication
The most obvious use of a Java interface is what its name implies—to specify the headings for a set of meth-
13.9 Interfaces 533
Apago PDF Enhancer
ods that a class must implement. A Java interface is a contract between a program de- signer and program implementers that standardizes communication among different classes. This use of interfaces is essential to the success of large programming projects.
Establish communication protocols early.
Suppose, for example, that you are designing an accounting system, and you’re cur-
rently focusing on “asset” accounts, which keep track of the value of things the company owns or has rights to. Typical asset accounts are: Cash, Accounts Receivable, Inventory, Furniture, Manufacturing Equipment, Vehicles, Buildings, and Land. These things are different from each other, so it would not be natural for classes representing them to be in a single inheritance hierarchy. Some of these accounts (Furniture, Manu- facturing Equipment, Vehicles, and Buildings) describe long-term or “fixed” assets whose values depreciate gradually over time. Each year, an accountant prepares a set of financial statements, like the Balance Sheet and a Profit and Loss Statement. This preparation requires access to the objects representing the depreciat- ing assets to get information like original cost, date of acquisition, and depreciation rate.
To facilitate this access, it would be nice to have references to these objects in a common array or ArrayList. Then a program could step through that array or ArrayList and call identically named polymorphic “get” methods to retrieve values of the originalCost, acquisitionDate, and depreciationRate instance variables in each object that represents a depreciating asset. Suppose that different programmers are writing the classes for different accounts. The best way to assure that all pro- grammers are “reading from the same page” is to require that all the classes that access a certain set of data