Chapter 9 Notes CSE 4301 (Java) Inheritance
I. Introduction A. Java does not support multiple inheritance of classes. B. But, a Java class can inherit both a class and an interface. C. A Java class can inherit only one level up; it, then, becomes the responsibility of the superclass to inherit it's superclass, etc. D. A subclass can not directly access the private members of its superclass. E. A subclass can directly access the following members of its superclass, provided it is in the same package as the superclass: 1. public members 2. protected members 3. package access members NOTE: a class can have members in all three of the above storage classes F. A subclass should override a method in it's superclass if: 1. The method is abstract in the superclass 2. The method is only stubbed in the superclass 3. The method's behavior (as defined in the superclass) is inappropriate for the subclass. II. Superclasses and Subclasses A. Inheritance models the "is-a" relationship by using a subclass to expand the definition of the superclass, thus providing a more restrictive subset of the objects belonging to the superclass. 1. A boss is an employee. 2. A cylinder is a circle. 3. A circle is a point. 4. A rectangle is a quadrilateral. B. The "is-a" relationship is not bidirectional. It is not true to say that a superclass (Employee) is a subclass (Boss). III. Protected members A. A superclass's public members are accessible anywhere the program has a reference to that superclass type or one of its subclass types. B. A superclass's protected access members may be accessed only by: 1. methods of the superclass 2. methods of subclasses of the superclass 3. methods of other classes in the same package (not true in C++) NOTE: protected members have package access C. An explicit cast can be used to convert a superclass reference to a subclass reference, but only if the superclass reference is actually referencing a subclass object. Any attempt to do otherwise will generate a ClassCastException. IV. Relationship between Superclass Objects and Subclass Objects A. The subclass must inherit the superclass: public class Circle extends Point B. The testing program does not inherit the superclass. It only in- stantiates objects of the subclasses. C. A subclass can explicitly pass arguments to it's superclass: super(a, b); D. If a subclass does not explicitly call the superclass's constructor, the default constructor in the superclass is called automatically at the point where the call to the superclass's constructor should have been ( super() ). F. If the subclass does not explicitly call a constructor in the super- class, and if the superclass does not have a default constructor, the compiler will generate an error. G. The call to the superclass's constructor must be the first statement in the subclass's constructor. Any other location will generate a compile- time error. H. If a subclass does not override methods defined in the superclass, the subclass can expect to use the methods as defined in the superclass: JApplet: init(), start(), toString(), paint() super.init(), super.start(), super.toString(), super.paint() Normally, a subclass overrides the method as defined in the superclass by first calling the method in the superclass and then doing some additional work. Not using the super reference to call the same method in the superclass results in infinite recursion because the subclass method actually calls itself. The super reference can only be used once per instruction. The following would generate a syntax error: super.super.x ********Figure 9.4, Point4.java, p. 391 Circle4.java, p. 391 InheritanceTest4.java, p. 392 V. Constructors and Finalizers in Subclasses A. Superclass constructors are not inherited by subclasses. B. If both super and sub classes have a finalize() method, the subclass finalize() should, if overriding the super's finalize(), call the superclass's finalize() method as it's last action, for purposes of garbage collection. C. Method finalize() in a superclass should always be defined as protected, to keep classes not inheriting from that class from having access to that finalize() method. *********Figure 9.5, Point5.java, p. 398 Circle5.java, p. 398 Test5.java, p. 399 VI. Implicit Subclass-Object-to-Superclass-Object Conversion A. Subclass objects can be treated as superclass objects (a subclass "is-a" superclass). B. An attempt to assign a superclass object to a subclass reference would leave additional subclass members undefined, and therefore is a syntax error. C. There are 4 possible ways to mix and match superclass and subclass references with superclass and subclass objects: 1. Refer to a superclass object with a superclass reference (normal) 2. Refer to a subclass object with a subclass reference (normal) 3. Refer to a subclass object with a superclass reference --safe, because the subclass object "is-a" object of the superclass -- such code can only refer to superclass members -- if this code refers to subclass-only members by using the superclass reference, the compiler will generate a syntax error 4. Refer to a superclass object with a subclass reference -- it is not true to say that a superclass "is-a" object of the subclass -- will generate a syntax error -- the subclass reference must first be cast to a superclass reference VII. Composition vs. Inheritance ("has-a" vs. "is-a") *********Figure 9.6, Point6.java, p. 403 Test6.java, p. 403 *********Figure 9.7, Circle7.java, p. 404 Test7.java, p. 404 *********Figure 9.8, Cylinder8.java, p. 407 Test8.java, p. 407 VIII. Introduction to Polymorphism A. With polymorphism, programs can be written to process generically (as superclass objects) objects of all existing classes in a hierarchy. B. Classes that do not exist during development can be added with little or no modifications to the generic part of the program, as long as those classes are part of the hierarchy that is being processed generically. IX. Type Fields and switch statements A. Selecting the appropriate behavior by using a switch statement based on the type of the object is error-prone: 1. The programmer might forget to make such a type test when one is warranted. 2. The programmer may forget to test all possible cases in a switch. 3. If a switch-based system is modified by adding new types, the programmer might forget to insert the new cases in existing switch statements. 4. Every addition or deletion of a class demands that every switch statement be modified, which is time consuming and error prone. B. Polymorphism is the preferred alternative to switch logic, for the opposite of the reasons listed in IX.A. above. X. Dynamic Method Binding A. Assume a superclass called Shape. B. Assume subclasses called Circle, Triangle, Rectangle, Square, etc. C. Declare the method draw() in the superclass, as well as in each subclass. D. If a superclass reference is used to refer to a subclass object, 1. and the draw() method is called via that superclass reference 2. the program will choose the correct subclass's draw() method at run time--dynamic method binding 3. In C++, the same applies, provided that the functions are virtual If they are not virtual, the call via the superclass reference would simply call the function in the superclass, if it is not pure virtual. XI. final methods and classes A. Variables can be declared final to indicate that they cannot be modified after they are declared and that they must be initialized when so declared. B. A method that is declared final cannot be overridden in a subclass. C. Methods that are declared static and methods that are declared private are implicitly final. D. The compiler can optimize the program by replacing calls to final methods with the code in that method's definition (inlining) XII. Abstract superclasses and Concrete Classes A. A class for which no objects are to be instantiated can be declared abstract: public abstract class X 1. The sole purpose of an abstract class is to provide an appropriate superclass from which other classes may inherit as an interface and/or implementation. 2. If a class is not abstract, it is considered to be concrete. 3. Multiple abstract classes can exist in an inheritance hierarchy. 4. An inheritance hierarchy does not have to have any abstract classes. XIII. Polymorphism A. In C++, polymorphism can be accomplished by doing the following in the context of an inheritance hierarchy: 1. All classes provide at least one function with the same signature. 2. That function is declared virtual in each class, perhaps even pure virtual in the base class. 3. A non-member function is called from another non-member function (virtualViaPointer() from main() ), passing to the first function a base class reference which had been assigned to a derived class object. 4. The first function (virtualViaPointer() ) knows to call the virtual function in the class of which the derived class object was instantiated, even though the reference was declared to be of the base class type. 5. If the functions are not virtual, then the polymorphic function (virtualViaPointer() ) will just call the base class version, if it is not pure virtual. B. In Java, polymorphism is accomplished by doing the following in the context of an inheritance hierarchy: 1. All classes must provide at least one non-final method with the same signature. 2. A superclass reference is assigned to a subclass object. 3. A method which expects the superclass reference will determine at run time which subclass of that superclass contains the method to be executed, and calls that method 4. The same message, sent to a variety of objects, thus takes on many forms--polymorphism. 5. The programmer can command a wide variety of objects to behave in manners appropriate to those objects without even knowing the types of those objects. XIV. Polymorphism case study **********Figure 9.9, Employee9.java, p. 414 **********Figure 9.9, Boss.java, p. 415 **********Figure 9.9, CommissionWorker.java, p. 415 **********Figure 9.9, PieceWorker.java, p. 416 **********Figure 9.9, HourlyWorker.java, p. 417 **********Figure 9.9, Test.java, p. 418 XV. Polymorphism case study **********Figure 9.10, Shape10.java, p. 421 **********Figure 9.10, Point10.java, p. 422 **********Figure 9.10, Circle10.java, p. 422 **********Figure 9.10, Cylinder10.java, p. 423 **********Figure 9.10, Test10.java, p. 424 XVI. Creating and Using Interfaces A. The abstract superclass can, alternatively, be an interface. 1. An interface definition begins with the keyword interface and contains a set of public abstract methods and/or public final static data. a. An interface containing method prototypes (p. 427) public interface Shape { public abstract double area(); public abstract double volume(); public abstract String getName(); } b. An interface containing data only (p. 432) public interface Constants { public static final int ONE = 1; public static final int TWO = 2; public static final int THREE = 3; } 2. To use an interface, a class must specify that it implements the interface. a. That class must then define every method in the interface with the exact signature and return type as specified in the interface definition. b. If that class leaves one or more methods in the interface undefined, the class itself becomes abstract and must be declared abstract in the first line of its class definition. NOTE: failure to so declare the class abstract will cause the compiler to generate a syntax error c. Implementing an interface is like signing a contract with the compiler that states, "I will define all the methods specified by the interface." B. ***********Figure 9.11, Shape.java (an interface), p. 427 ***********Figure 9.11, Point11.java, p. 428 ***********Figure 9.11, Circle11.java, p. 429 ***********Figure 9.11, Cylinder11.java, p. 428 ***********Figure 9.11, Test11.java, p. 431 XVII. Inner Class Definitions A. A class can be defined within another class definition. 1. Such a class can be a. completely defined, including the class name, or b. anonymous--having no class name B. An inner class is used when it has no bearing on the outer class's interface to external clients. C. Inner classes are frequently used with GUI event handling. **********Figure 9.12, Time12.java, p. 433 **********Figure 9.12, TimeTestWindow12, p. 434 D. Compiling a class with inner classes results in a separate .class file for every class. 1. Inner classes with names have the compiled file name OuterClassName$InnerClassName.class 2. Anonymous inner classes have the compiled file name OuterClassName$#.class where # starts at 1 and is incremented for each anonymous inner class encountered during compilation. 3. To use the outer class's this reference, use OuterClassName.this E. The outer class is responsible for creating any objects of its inner classes. F. To create an object of another class's inner class, first create an object of the outer class and assign it to a reference, such as ref. Then create an inner class object: OuterClassName.InnerClassName innerRef = ref.new InnerClassName(); G. An inner class can be declared static. 1. A static inner class does not require an object of its outer class to be defined (but a non-static inner class does). 2. A static inner class does not have access to the outer class's non-static members. XVIII. Type-Wrapper Classes for Primitive Types A. Each of the primitive data types has a type-wrapper class: type-wrapper class name inherits from 1. Character 2. Byte Number 3. Short Number 4. Integer Number 5. Long Number 6. Float Number 7. Double Number 8. Boolean B. Each type-wrapper class enables primitive types to be treated as objects of class Object. 1. Therefore, values of the primitive data types can be processed polymorphically if they are maintained as objects of the type-wrapper classes. C. Each type-wrapper is final D. Many of the methods that process the primitive data types are static methods of the type-wrapper classes.


This page was last updated on 05.08.2000.