Transcript
Computer Science Notes
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:
To recognize when you should break up a class into superclasses and subclasses.
To correctly use constructors from a superclass.
To correctly overload or override methods of a superclass in one of its subclasses.
To correctly implement some of the fundamental methods in the Object superclass.
Book’s Statement of Skills:
To develop a subclass from a superclass through inheritance. (10.2)
To illustrate inheritance by creating a custom frame that extends JFrame. (10.3)
To invoke the superclass’s constructors and methods using the super keyword. (10.4)
To override instance methods in the subclass. (10.5)
To distinguish differences between overriding and overloading. (10.6)
To explore the methods toString(), and equals(Object) in the Object class. (10.7)
To discover polymorphism, dynamic binding, and generic programming. (10.8)
To describe casting and explain why explicit downcasting is necessary. (10.9)
To store, retrieve, and manipulate objects in an ArrayList. (10.10)
To implement a Stack class using an ArrayList. (10.11)
To restrict access to data and methods using the protected visibility modifier. (10.12)
To prevent class extending and method overriding using the final modifier. (10.13)
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
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
public final class Integer
extends Number
implements Comparable
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
TYPE
The Class instance representing the primitive type int.
Constructor Summary
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.
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.
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
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.
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.
For example, a circle “is a” geometric object.
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.
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
Section 10.4: Using the super keyword
The super keyword is used to refer to the superclass of the class in which super appears.
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…
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.
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
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.
+Object()
Constructs a default Object.
+clone():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()
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;
}
Section 10.8: Polymorphism, Dynamic Binding, and Generic Binding
Pillars of object-oriented programming:
Encapsulation
Inheritance
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).
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...