Computer Science Notes Chapter 11 Page 1 of 11 Chapter 11: Inheritance and Polymorphism These notes are meant to accompany Introduction to Java Programming: Brief Version, eighth edition by Y. Daniel Lang. Programming Skills in a Nutshell: At the end of this chapter you should have the following programming skills: 1. To recognize when you should break up a class into superclasses and subclasses. 2. To correctly use constructors from a superclass. 3. To correctly overload or override methods of a superclass in one of its subclasses. 4. To correctly implement some of the fundamental methods in the Object superclass. Book’s Statement of Skills: 1. To develop a subclass from a superclass through inheritance. (10.2) 2. To illustrate inheritance by creating a custom frame that extends JFrame. (10.3) 3. To invoke the superclass’s constructors and methods using the super keyword. (10.4) 4. To override instance methods in the subclass. (10.5) 5. To distinguish differences between overriding and overloading. (10.6) 6. To explore the methods toString(), and equals(Object) in the Object class. (10.7) 7. To discover polymorphism, dynamic binding, and generic programming. (10.8) 8. To describe casting and explain why explicit downcasting is necessary. (10.9) 9. To store, retrieve, and manipulate objects in an ArrayList. (10.10) 10. To implement a Stack class using an ArrayList. (10.11) 11. To restrict access to data and methods using the protected visibility modifier. (10.12) 12. To prevent class extending and method overriding using the final modifier. (10.13) Computer Science Notes Chapter 11 Page 2 of 11 java.lang Class Number java.lang.Object java.lang.Number All Implemented Interfaces: Serializable Direct Known Subclasses: AtomicInteger, AtomicLong, BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short public abstract class Number extends Object implements Serializable The abstract class Number is the superclass of classes BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, and Short. Subclasses of Number must provide methods to convert the represented numeric value to byte, double, float, int, long, and short. Since: JDK1.0 See Also: Byte, Double, Float, Integer, Long, Short, Serialized Form Constructor Summary Number() Method Summary byte byteValue() Returns the value of the specified number as a byte. abstract double doubleValue() Returns the value of the specified number as a double. abstract float floatValue() Returns the value of the specified number as a float. abstract int intValue() Returns the value of the specified number as an int. abstract long longValue() Returns the value of the specified number as a long. short shortValue() Returns the value of the specified number as a short. Methods inherited from class java.lang.Object Computer Science Notes Chapter 11 Page 3 of 11 clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait java.lang Class Integer java.lang.Object java.lang.Number java.lang.Integer All Implemented Interfaces: Serializable, Comparable<Integer> public final class Integer extends Number implements Comparable<Integer> The Integer class wraps a value of the primitive type int in an object. An object of type Integer contains a single field whose type is int. In addition, this class provides several methods for converting an int to a String and a String to an int, as well as other constants and methods useful when dealing with an int. Implementation note: The implementations of the "bit twiddling" methods (such as highestOneBit and numberOfTrailingZeros) are based on material from Henry S. Warren, Jr.'s Hacker's Delight, (Addison Wesley, 2002). Since: JDK1.0 See Also: Serialized Form Field Summary static int MAX_VALUE A constant holding the maximum value an int can have, 231-1. static int MIN_VALUE A constant holding the minimum value an int can have, -231. static int SIZE The number of bits used to represent an int value in two's complement binary form. static Class<Integer> TYPE The Class instance representing the primitive type int. Constructor Summary Computer Science Notes Chapter 11 Page 4 of 11 Integer(int value) Constructs a newly allocated Integer object that represents the specified int value. Integer(String s) Constructs a newly allocated Integer object that represents the int value indicated by the String parameter. Method Summary static int bitCount(int i) Returns the number of one-bits in the two's complement binary representation of the specified int value. byte byteValue() Returns the value of this Integer as a byte. int compareTo(Integer anotherInteger) Compares two Integer objects numerically. static Integer decode(String nm) Decodes a String into an Integer. double doubleValue() Returns the value of this Integer as a double. boolean equals(Object obj) Compares this object to the specified object. float floatValue() Returns the value of this Integer as a float. static Integer getInteger(String nm) Determines the integer value of the system property with the specified name. static Integer getInteger(String nm, int val) Determines the integer value of the system property with the specified name. static Integer getInteger(String nm, Integer val) Returns the integer value of the system property with the specified name. int hashCode() Returns a hash code for this Integer. static int highestOneBit(int i) Returns an int value with at most a single one-bit, in the position of the highest-order ("leftmost") one-bit in the specified int value. int intValue() Returns the value of this Integer as an int. long longValue() Returns the value of this Integer as a long. static int lowestOneBit(int i) Returns an int value with at most a single one-bit, in the position of the lowest-order ("rightmost") one-bit in the specified int value. static int numberOfLeadingZeros(int i) Returns the number of zero bits preceding the highest-order ("leftmost") one-bit in the two's complement binary representation of the specified int value. Computer Science Notes Chapter 11 Page 5 of 11 static int numberOfTrailingZeros(int i) Returns the number of zero bits following the lowest-order ("rightmost") one-bit in the two's complement binary representation of the specified int value. static int parseInt(String s) Parses the string argument as a signed decimal integer. static int parseInt(String s, int radix) Parses the string argument as a signed integer in the radix specified by the second argument. static int reverse(int i) Returns the value obtained by reversing the order of the bits in the two's complement binary representation of the specified int value. static int reverseBytes(int i) Returns the value obtained by reversing the order of the bytes in the two's complement representation of the specified int value. static int rotateLeft(int i, int distance) Returns the value obtained by rotating the two's complement binary representation of the specified int value left by the specified number of bits. static int rotateRight(int i, int distance) Returns the value obtained by rotating the two's complement binary representation of the specified int value right by the specified number of bits. short shortValue() Returns the value of this Integer as a short. static int signum(int i) Returns the signum function of the specified int value. static String toBinaryString(int i) Returns a string representation of the integer argument as an unsigned integer in base 2. static String toHexString(int i) Returns a string representation of the integer argument as an unsigned integer in base 16. static String toOctalString(int i) Returns a string representation of the integer argument as an unsigned integer in base 8. String toString() Returns a String object representing this Integer's value. static String toString(int i) Returns a String object representing the specified integer. static String toString(int i, int radix) Returns a string representation of the first argument in the radix specified by the second argument. static Integer valueOf(int i) Returns a Integer instance representing the specified int value. static Integer valueOf(String s) Returns an Integer object holding the value of the specified String. Computer Science Notes Chapter 11 Page 6 of 11 static Integer valueOf(String s, int radix) Returns an Integer object holding the value extracted from the specified String when parsed with the radix given by the second argument. Methods inherited from class java.lang.Object clone, finalize, getClass, notify, notifyAll, wait, wait, wait Computer Science Notes Chapter 11 Page 7 of 11 Section 10.1: Introduction Inheritance is the programming technique where new classes are derived from existing classes by “inheriting” data fields and methods from those existing classes. For example, classes to model circles and rectangles could inherit some data fields and methods from a general object for geometric objects. The general geometric object might include methods and data fields that would be common to all geometric objects in general, like the color to use when drawing the object. These methods would be inherited by the circle and rectangle classes, because they both need a color choice for graphing. Additional data fields like a radius for a circle object and side lengths for a rectangle object would be specified in those classes, because that is additional info particular to those objects, and are not generally applicable to any geometric object. Additional methods like computing the area and perimeter would be in the rectangle and circle classes only, because those calculations are not the same for any general geometric object. Adding subclasses to a given class is called extending the given class. All the classes we have used or implemented ourselves up to this point implicitly extended the java.lang.Object class. In fact, the structure of the Java language is that all classes must either implicitly or explicitly extend the class java.lang.Object. Computer Science Notes Chapter 11 Page 8 of 11 Section 10.2: Superclasses and Subclasses In Java terminology, if a class C1 is extended from another class C2, then the class C1 is called the subclass, and the class C2 is called the superclass. Synonyms for superclass: parent class, base class Synonyms for subclass: child class, extended class, derived class. A subclass inherits accessible data and methods from its superclass, and may also add new data fields and methods. Subclasses are denoted in UML diagrams with an arrow pointing from the subclass to the superclass. To declare that a class is a child of a superclass, use the extends keyword when implementing the class: class SubclassName extends SuperclassName { //new data fields //constructors //new methods //overridden methods //overloaded methods } Some design concepts worth considering when working with inheritance: A subclass is not a subset of its superclass. In fact, a subclass usually contains more information and methods than its superclass. Inheritance is used to model the “is – a” relationship. o For example, a circle “is a” geometric object. o Do not blindly extend a class just for the sake of reusing methods. For example, do not have a Tree class extend a Person class just to use methods like getHeight() and getWeight() that might be common to both classes. Only “is – a” relationships where the subclass contains more detailed information than the superclass should be modeled using inheritance. o For example, even though a rhombus “is a” parallelogram, a rhombus does not contain any more detailed information than a parallelogram does, and so a Rhombus class should extend a geometric object class (and not a Parallelogram class). Java only allows one parent class when the extends keyword is used. This is called single inheritance. See www.cs.armstrong.edu/liang/intro7e/book/GeometricObject1.java See www.cs.armstrong.edu/liang/intro7e/book/Circle4.java See www.cs.armstrong.edu/liang/intro7e/book/Rectangle1.java See www.cs.armstrong.edu/liang/intro7e/book/TestCircleRectangle.java Section 10.3: Extending the JFrame Class See www.cs.armstrong.edu/liang/intro7e/book/UseCustomFrame.java Computer Science Notes Chapter 11 Page 9 of 11 Section 10.4: Using the super keyword The super keyword is used to refer to the superclass of the class in which super appears. o Contrast to the this keyword, which refers to the calling object itself. The super keyword can be used to call a superclass constructor. The super keyword can be used to call a superclass method. The super keyword can be used to refer to a superclass’s visible data fields. Section 10.4.1: Calling Superclass Constructors The statement super() invokes the no-arg constructor of the superclass. The statement super(arguments) invokes the constructor of the superclass with the matching arguments. The call to the superclass’s constructor must be the first line of the subclass’s constructor. Constructors of the superclass are not inherited by the subclass. Section 10.4.2: Constructor Chaining If you don’t explicitly invoke one of the superclass’s constructors, the compiler inserts a super() as the first line of code in your constructor for you. A superclass’s constructor is called before the subclass’s constructor. This is called constructor chaining. This happens all the way up the inheritance chain. If a class is defined to be extended, then you should provide a no-arg constructor. Section 10.4.3: Calling Superclass Methods The syntax super.methodName(parameters) invokes the method called methodName from the parent class. Chaining of supers is not allowed in java… o i.e., super.super.p(); Section 10.5: Overriding Methods When overriding a method of a superclass: Supply a different implementation of a method that exists in the superclass Must have same signature (same name and same parameter types) If a method is applied to an object of the subclass type, the overriding method is executed Private data fields in a superclass are not accessible to subclasses. They can only be accessed through accessor/mutator methods of the superclass. Private methods in the superclass can not be overridden, because only accessible methods can be overridden. Static methods in the superclass can not be overridden. If you try, then the static method in the superclass is hidden, and can only be accessed by calling the static method of the superclass explicitly. Data fields in the superclass can not be overridden. Section 10.6: Overriding vs. Overloading To overload a method of the superclass: Supply a different implementation (with a new signature) of a method that exists in the superclass. (Same as before…) Overridden methods have the same signature (list of parameters) and same return type. Overloaded methods have a different signature or different return type. Computer Science Notes Chapter 11 Page 10 of 11 Section 10.7: The Object Class and Its Methods Every class in Java is descended from the java.lang.Object class. If no inheritance is specified, then the superclass of the class is Object by default. Thus, all classes inherit the following behavior from the Object class: java.lang.Object +Object() +clone():Object Class Object is the root of the class hierarchy. Every class has Object as a superclass. All objects, including arrays, implement the methods of this class. Constructs a default Object. Creates and returns a copy of this object. +equals(obj: Object): boolean Indicates whether some other object is "equal to" this one. +finalize(): void Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. +getClass(): Class<?> Returns the runtime class of this Object. +hashCode():int Returns a hash code value for the object. +notify():void Wakes up a single thread that is waiting on this object's monitor. +notifyAll():void Wakes up all threads that are waiting on this object's monitor. +toString():String Returns a string representation of the object. +wait():void Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. +wait(timeout: long): void Causes the current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed. +wait(timeout: long, nanos: int): void Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed. Two familiar-looking methods: toString() o System.out.println(object) is equivalent to System.out.println(object.toString()) equals() default implementation in the Object class is: public boolean equals(Object obj) { return (this == obj); } public boolean equals(Object obj) { if(obj instanceof Circle) return this.radius == ((Circle)obj).radius; else return false; } Computer Science Notes Chapter 11 Page 11 of 11 Section 10.8: Polymorphism, Dynamic Binding, and Generic Binding Pillars of object-oriented programming: o Encapsulation o Inheritance o Polymorphism The type of a variable is object type it is declared as. Every instance of a subclass is an instance of the superclass (but not vice-versa). o Every circle is a geometric object but not every geometric object is a circle. Therefore, you can always pass an instance of a subclass to a parameter of its superclass type. Polymorphism: a variable of a supertype can refer to a subtype object. The JVM can search “up a tree” of superclasses to find the correct method to use without the class that the method belongs to being specified before the program is run. This is called dynamic binding. A huge benefit of dynamic binding is that new classes can be loaded on the fly without recompilation. Generic programming involves writing code that takes advantage of polymorphism so that a method can be used generically for a wide range of objects. See www.cs.armstrong.edu/liang/intro7e/book/PolymorphismDemo.java Section 10.9: Casting Objects and the instanceof Operator Casting can not only be used to convert primitive variables from one type to another, but can also be used to convert an object of one class type to another within an inheritance hierarchy. Implicit casting (when a more generic object is set equal to a subclass) example: Object o = new Student(); Explicit casting (when a more subclass-typed variable is set equal to a superclass that was initialized as a specific subclass) example: Student b = (Student) 0; Upcasting: casting an instance of a subclass to a variable of a superclass (always allowable, because a subclass is always an instance of its superclass) Downcasting: casting an instance of a superclass to a variable of a subclass (only allowable when the object to be cast is an instance of the subclass) The instanceof operator can be used to determine when an object to be cast is an instance of the subclass See www.cs.armstrong.edu/liang/intro7e/book/TestPolymorphismCasting.java Section 10.10: The ArrayList Class Section 10.11: A Custom Stack Class Section 10.12: The protected Data and Methods Can only be accessed by any classes in same package, or by subclasses. Section 10.13: Preventing Extending and Overriding Modify as final...