Chapter 3: Inheritance and Polymorphism
Chapter 3: Inheritance and Polymorphism
Inheritance:
Inheritance: Defines a relationship between objects that share characteristics.
It is the mechanism by which a new class, called a subclass, is formed from an existing class, called a superclass.
When a subclass inherits characteristics from the superclass, methods and characteristics from the superclass are
available to use by objects created from the subclass.
In addition, a subclass is still usually bigger than a superclass, because (usually) it contains more methods
(constructors, accessors, and mutators), as well as more data.
Inheritance Hierarchy: When the subclass itself is a superclass for another subclass.
Method Overriding: When a subclass redefines a certain method that it has inherited from its superclass. For example,
this may happen if the superclass is Student, and the subclass is GradStudent. Thus, a method in Student that
calculates GPA may be changed and overriden in GradStudent.
Partial Overriding: If part of the original method implementation from the superclass is retained.
Every subclass inherits the public or protected variables and methods of its superclass.
Implementing Subclasses:
Extends Keyword:
Extends Keyword: The extends keyword, found right after the declaration of the subclass as in "public class SubClass
extends Superclass"
Private data, although previously stated that they can't be directly accessed, are a little bit tricky. They cannot be
directly accessed, but they can be accessed indirectly, ie. the subclass invokes the public accessor or mutator or
constructors that are public in the superclass. Thus, since these methods use the private instance variables, they can
still be accessed in the subclass.
Finally, this is an easy one. Just remember that classes on the same level in a hierarchy diagram do not inherit anything
from each other.
Partial Overriding: Partial overriding occurs when the subclass method wants a certain method inherited from the
superclass to do something extra. In this case, the method is once again redefined, as in method overriding, with the
same return type and signature (name and parameter type). Then, inside of its implementation, the keyword super() is
used.
For example, if there is a public method from the superclass called computeGrade(), and you want to add some
functionality to that in the subclass, simply redefine the function (public void computeGrade() {}) and inside of the
braces, write (super.computeGrade()) to import everything from the superclass's version of the computeGrade()
method. Finally, add any other or any additional lines in the subclass's version of computeGrade()'s
implementation.
The subclass needs its own constructor. Thus, this means that if the subclass constructor is not declared, the program
will attempt to use the superclass default constructor with no parameters. If the superclass has no default constructor
(which is why it's good practice to always put one in), then the compiler will give a compiler error. All assuming, there
is no subclass constructor. Lesson: Create a subclass constructor too!
If this occurs, then additional instance variables in the subclass will be initialized in a default manner. This means
that subclass - specific instance variables that are integers will be 0, strings will be null.
For the equations below, assume in the superclass there are 3 variables: variable1, variable2, and variable3.
If super is used in the implementation of a subclass constructor, it must be used in the first line of the constructor
body.
If no constructor is provided in a subclass, the compiler provdes the following default constructor: This is the same on
the on the left hand side above.
Subclass Rules:
A subclass can add new private instance variables.
Polymorphism
A method that has been overriden in at least one subclass is said to be polymorphic. Polymorphism is the mechanism
of selecting the appropriate method for a particular object in a class hierarchy.
The reason polymorphism works is because the correct method is chose due to the class of the object itself, not
the type of the object reference. All that means is that we can have something like this: SuperClass Object1 = new
SubClass();
Remember that the selection of the correct program happens during the run of the program.
All this means is that the decision to use a certain method is made while the program is running, not at compile time. It
is important to note that the only elements that go through static binding, when the decision is made during compile -
time, are static, private, and final members (methods and variables).
Overloading occurs when there is a method with the same name but not the same signature found in the same class.
This process is called overloading, and undergoes static binding. Here, the method in the main function corresponds
with the one in the class with the same parameters and signature and name.
In any case, due to polymorphism, the method will follow the SubClass's version.
For example, Student s = new GradStudent(); is an instance where reference variable "s" represents a GradStudent
object, but is in terms of Student (the superclass).
Thus, s.getID; where getID is a method unique to GradStudent, is unavailable. In order to fix this one may use
downcasting:
You need the outer parentheses because the dot operator holds greater significance than the downcasting, so you
need outer parentheses to make sure the object s gets downcasted from a superclass type to a subclass type.
This means you can only downcast to subclass, not any random class.
Abstract Classes
Abstract classes are superclasses that represent an abstract concept.
An abstract class may contain abstract methods. These are methods that have no implementation code, just a header.
There is no reason or purpose for it in the superclass other than as a placeholder. The method's implementation
appears in the subclasses. If a class contains any abstract methods, it must be declared an abstract class.
It also must be present in any abstract method's declaration, wherever that declaration of that method with no
implementation is.
It is also possible for an abstract class to have no abstract methods. This occurs when an abstract subclass of an
abstract superclass inherits the abstract methods without explicitly declaring them.
An abstract class may or may not have constructors. In addition, no instances can be created for an abstract class.
However, the reference variable may belong to the abstract class, its just that the object it references must be one of a
class that is not abstract.
Interfaces
An interface is a collection of related methods. They are must have only abstract methods, and may not contain any
instance variables. They may, however, contain static final variables, and static final variables only.
Interfaces, unlike abstract classes do not group together similar objects in terms of what they are representing, and
instead group together similar objects in terms of what they can / supposed to do.
For instance, if there is a game of battleship, there may be a public abstract class called Ship, with public classes
Battleship, Destroyer, etc..
However, the methods that such classes will need include moveuponespace(), movedownonespace() as these ships
need to move up and down on the 2D grid. Thus, for this, you can have an interface using the implements
keyword, which can be used for any object that can move up and down on the 2D plane, including fish, sharks, and
ships, which are not common in nature but common in the way they can move on the 2D plane