Inheritance
Objective #1: Explain inheritance.
- Inheritance in Java allows a class developer programmer to efficiently build one class from another class. Rather than having to "re-invent the wheel", a class developer can take advantage of the methods in one class and automatically include them in another class plus add some more of his/her own methods. The new class that is based upon the original class is called a subclass (aka child class or derived class). The original class is known as the superclass (aka parent class or base class).
- A child class can only be based on one parent class in Java.
- Use the keyword extends to create a subclass as in
public class CheckingAccount extends BankAccount
or
public class SlowFish extends Fish
If a class implements one or more interfaces and extends a parent class, you use syntax like this where the keyword extends must be before the keyword implements:
public class SlowFish extends Fish implements Comparable, Swimmable
- The relationship between a subclass such as Student and its superclass such as Person is called an is-a
relationship. That is, a Student is a Person but you can't necessarily say that a Person is a Student. The is-a relationship is transitive. So if Freshmen is-a subclass of Student and if Student is-a subclass of Person then you can say that a Freshman object is-a Person.
- Assume that Freshman is a subclass of Student and that Student is a subclass of Person.
The following statements are VALID.
Example 1/
Person john = new Student();
john is declared as a Person reference but behind-the-scenes john is instantiated as a Student object. This is legal however only the methods found in the Person class can be invoked. However, if john is casted to a Student, then methods from the Student class can be invoked.
Example 2/
Person sally = new Freshman();
sally is declared as a Person reference but behind-the-scenes sally is instantiated as a Freshman object. This is a legal but only the methods found in the Person class can be executed. However ,if sally is casted to a Student, then the methods from the Student class can be invoked. If sally is casted to a Freshman, then methods from the Freshman class can be used.
Example 3/
Person
person1 = new Person();
Person person2 = new Person();
person2 = person1;
is legal but remember the assignment statement is really only copying a memory address (i.e. aliasing).
Example 4/
Person
person1 = new Person();
Student student1 = new Student();
person1 = student1;
is legal. However there could be "information loss" since the possible extra non-inherited fields in the Student object are not necessary
in the Person object.
The following statements are NOT VALID.
Example 5/
Student fred = new Person();
is illegal.
Example 6/
Person
person1 = new Person();
Student student1 = new Student();
student1 = person1;
is illegal since a Student object possibly has additional instance fields that a Person object doesn't have. What would Java store in those additional fields if this were legal?
- An interface can extend another interface. For example you could have
public interface Movable extends Locatable
In fact, an interface can extend multiple interfaces as in
public interface Movable extends Locatable, Comparable
- A class hierarchy chart is a diagram where each class is represented with a rectangle and they are connected with arrows to show the is-a relationship between inherited classes. Parent classes are drawn at the top of the chart.
A solid line with a solid arrowhead is drawn from a child class to the parent class that it extends.This indicates an "is-a" relationship.
A dotted line with a solid arrowhead is used to point from a class to an interface that it implements.
A solid line with an open arrowhead is drawn from a class to a class that it has a "has-a" relationship with. For example, if a Student class has a Notebook property then you would draw a line with an open arrowhead pointing from the Student class to the Notebook class.
Classes in the same level of a hierarchy chart are called sibling classes.
A UML (Unified Modeling Language) diagram goes even further than a class hierarchy chart in illustrating the inheritance relationships between classes. We will not formally study UML diagrams this year, but in a college programming course you would probably need to use them.
Objective #2: Inherit methods and properities from a superclass, override methods from a superclass, and add new methods to a subclass.
- All public methods of a superclass are automatically
inherited by a subclass. Public methods can be used by client programmers while protected methods cannot.
- All properties of a superclass are inherited by a subclass. However, a programmer cannot directly refer to any of the inherited properties in the superclass if they are private.
It is common to use the inherited public accessor and modifier methods to access or modify the inherited private instance fields. For example, you may inherit your grandfathers liquor or gun collection when he passes away, but you still can't make use of those items since they are "private" (i.e. you aren't 21 years old yet.)
- A subclass can have its own additional public, private, or static methods that are not inherited from its superclass. This allows a class to have new behavior that the superclass didn't need or that wasn't relevant for the superclass. A subclass can also have new instance fields (i.e. properties) that didn't exist in the parent class.
- If you wish a method to perform differently in a subclass from the way that it performs in the superclass, you can override the method by typing another implementation in the subclass. A method must have the same return type and method signature (parameters and parameter types) as the method that it overrides.
- A subclass may not override a public method from its superclass as private.
- If a method is marked final in a superclass, then that method cannot be overridden in a subclass. For example,
public final void run() { ... }
while the method run may be called within a client program or subclass, the method cannot be overridden in a subclass.
- If the original method from the superclass is called in the subclass's version of an overriding method it is called partial overriding. You can use the keyword super to invoke the method from the superclass.
- A subclass may not override static methods from its superclass.
- Even though public methods are inherited from a superclass, the private methods of a superclass can still be overridden in the subclass.
- When a property in a subclass has the same exact name as a property in the superclass, it is called shadowing. Shadowing does not cause a compile error but it is not wise. It can easily confuse other programmers having two properties in related classes with the same name.
- The default access for a class or a method or property within a class is package. That is, if you do not specify (or forget to specify) whether a method or property
is public or private, Java will allow any class within the package to use that method or property. Remember from our earlier studies that a package is a collection of classes like java.util or java.math.
Normally, it is not a good idea to allow methods or especially properities to have package access. As we have already studied, you should usually give properties an access of private and
methods should be public. Constants should usually be public as well.
- A subclass does not automatically realize any interfaces that are realized (i.e. implemented) by its superclass. For example, a superclass could implement a method from an interface
that it implements as a final method. In this case, the subclass cannot implement this method and therefore would not be able to implement the interface.
Objective #3: Invoke inherited methods.
- A method that is overriden in at least one subclass is called polymorphic.
- When methods are overloaded and they have different method signatures, the compiler selects the correct version of a method at compile time. This process is called early binding (aka static binding). Do not confuse the term overload with override!
- When the Java Virtual Machine determines which version of an overridden, polymorphic method to execute at runtime, it uses the type of the actual instantiated object and not the type of the object reference. This determination occurs at run-time and is called late-binding (aka dynamic binding). It is very, very important that you understand this for the AP exam!
- From within the subclass, you can specifically
call the version of the overridden method by using the keyword super.
- Study the following examples:
public class SuperClass
{
public void A()
{
System.out.println("super A");
}
public void B()
{
A();
}
}
public class SubClass extends SuperClass
{
public void A()
{
System.out.println("sub A");
}
public void C()
{
super.A();
}
}
Example 1/
The client code
SubClass thing = new SubClass();
thing.B();
will display the output
sub A
since the subclass' overridden version of A will be invoked even though it seems as if it's being invoked from within the SuperClass.
It's not really being invoked from within SuperClass since SubClass has
its own overridden version of A().
Example 2/
The client clode
SubClass thing = new SubClass();
thing.C();
will display the output
super A
since the C method is specifically invoking the SuperClass version of the A method with the use of the super keyword.
Example 3/
SuperClass thing = new SubClass();
thing.C();
will result in compile error since the SubClass object is "cloaked" as a SuperClass reference. In other words, it is only legal to invoke methods that are found in SuperClass since due to this SuperClass reference.
Example 4/
SuperClass thing = new SubClass();
thing.A();
will display the output
sub A
since the compiler will automatically invoke the version of A found in the SubClass, even though thing is "cloaked" as a SuperClass reference.
Example 5/
SuperClass sup = new SuperClass();
SubClass sub = new SubClass();
sup = sub;
sup.A();
will display the output
sub A
since the compiler will automatically invoke the version of A found in the SubClass,
because the object variable sup now stores the object memory reference that is stored in sub.
So sup really is a SubClass object deep down and invokes the method in the subclass.
Example 6/
SubClass thing = new SuperClass();
thing.A();
will cause a compile error since it is illegal to "cloak" a superclass object with a reference to its subclass.
- It is legal and necessary to cast an object to the type necessary to make use of an available method. Using the same classes as illustrated above, study the following examples:
Example 7/
SuperClass thing = new SubClass();
((SubClass) thing).C();
is legal since thing, which was "cloaked" as a SuperClass reference, is casted to the SubClass that he really is "deep down under the cloak". Without being casted, it would cause a compile error to try to invoke the method C on a SuperClass reference since there is no method named C in the SuperClass class.
Example 8/
SuperClass thing = new SuperClass();
((SubClass) thing).C();
The cast in this example is illegal and causes an ClassCastException run-time
error since thing is only instantiated as a SuperClass object.
He can never be turned into or casted into a SubClass object.
Objective #4: Invoke superclass constructors.
- Constructors of a superclass are not inherited by a subclass. Therefore, a subclass must define its own constructors since they are not inherited.
- However, you can invoke a constructor of a superclass (assuming its public which it most likely is) with the statement super(); . If you want to call the superclass' constructor, you must do so on the first line of the subclass constructor.
Study the following examples:
public class SuperClass
{
public SuperClass()
{
System.out.println("super constructor ");
num = 10;
}
public SuperClass(int amount)
{
System.out.println("other super constructor");
num = amount;
}
private int num;
}
public class SubClass extends SuperClass
{
public SubClass()
{
super();
System.out.println("sub constructor");
age = 5;
}
public SubClass(int amount)
{
System.out.println("other sub constructor");
num = 2 * amount;
age = 5;
}
private int age;
}
Example 1/
The client code
SubClass thing = new SubClass();
will display the output
super constructor
sub constructor
Example 2/
The client code
SuperClass thing = new SubClass();
will display the output
super constructor
sub constructor
since the constructor from the SubClass is being invoked. Remember that constructors are not inherited.
Example 3/
The client code
SubClass thing = new SubClass(8);
will display the output
super constructor
other sub constructor
since the default constructor of the superclass is automatically called from within the "other constructor" of the subclass whether it is invoked with the statement super(); or not.
Objective #5: Override its toString and equals methods from the Object superclass.
- The Object class is the "cosmic" superclass of all classes.
In other words, the Object class is found at the top of the Java class
hierarchy chart. All classes that you create automatically extend the Object class. Do not type "extends Object" in your own classes. Therefore all methods found in the Object class are inherited
by all classes even ones that you create from scratch.
- The methods toString and equals are found in the Object class
and should be understood for the AP exam. The additional methods clone and
hashCode are also found there but they are not covered on the
AP exam.
- It is efficient and wise to override the toString method in any class that
you create so you have any easy way to examine the state of an object variable
for debugging purposes. When overriding the toString method, you should return
a string that shows the properties and values of an object. If you don't
override the toString method, the inherited Object class's toString method
is used but it returns the object's hash code.
- The following is an example of an overridden toString method in a fictious
Student class that contains firstName, lastName, and gpa properties:
public String toString()
{
return "first = " + firstName + " last = " + lastName
+ " gpa = " + gpa;
}
Be careful not to make the return type void and to use System.out.println from within the toString method
since it is required to return a string.
- In a client class, the System.out.println method
can be used to invoke the toString method as in
System.out.println(widget.toString());
or
System.out.println(widget);
The latter is preferable since the println method automatically invokes an
object's toString method when the object is a parameter of the println method.
- To override the equals method from the Object class, you must use the header
public boolean equals(Object other)
- Ordinarily, you would compare each property of the this object with the corresponding property of the parameter and return true if they are all equal and false otherwise.
For example, in a fictious Student class that contains firstName, lastName,
and gpa properties:
public boolean equals(Object other)
{
if (firstName.equals(((Student) other).firstName) && lastName.equals(((Student) other.lastName) && gpa == ((Student) other).gpa))
{
return true;
}
return false;
}
- If the compareTo method from the Comparable interface is implemented, then you
could use
public boolean equals(Object other)
{
return compareTo(other) == 0;
}
Objective #6: Use abstract classes and abstract methods
- An abstract class is one that uses the abstract keyword in its header as in
public abstract class Solid
- Zero or more methods can be made abstract in an abstract class. An abstract method is a method that does not have an implementation.
- If a class fully implements all of its methods and does not use the abstract keyword, then it is called a concrete class. Classes that we wrote and studied for the first half of the school year were considered to be concrete classes.
- Subclasses that are extended from an abstract parent class may fully implement one or more of the abstract methods. If a subclass of an abstract class does not implement all of the abstract methods then it is also considered to be an abstract class.
- Sometimes no methods of an abstract class are defined as abstract! This is done simply to prevent a client programmer from constructing (i.e. instantiating) objects of the abstract class.
- Unlike an interface, an abstract class can include instance fields and it can include some fully implemented methods.
- Methods in an abstract class can be private. Note that this is another difference between abstract classes and interfaces, which can only have public methods.
- It is not possible to construct (i.e. instantiate) an object from an abstract class just like it is not possible to instantiate an object from an interface. The following statement would cause an error.
MyAbstractClass example = new MyAbstractClass();
But it is possible to simply declare a reference to an abstract class.
MyAbstractClass example;
It is also possible to set a reference of an abstract class equal to null as in
MyAbstractClass example = null;
- If Solid is an abstract class and if Sphere is a concrete subclass of Solid the following is legal
Solid example = new Sphere();
or
Solid example;
example = new Sphere();
- A class can implement an interface and only implement some of the methods from the interface. In this case, the class must be declared as abstract. The class doesn't need to include method signatures for the abstract methods that were not implemented.
- Here is a complete example of an abstract class named ModelStudent, a concrete class named Sophomore, and a client program:
public abstract class ModelStudent
{
private double gpa;
public abstract void doHomework();
public void attendClass()
{
System.out.println("Hi, I'm here in class");
}
}
public class Sophomore extends ModelStudent
{
public void doHomework()
{
System.out.println("Sophomores do their homework immediately when they get home");
}
}
public class AbstractClassDemo
{
public static void main(String[] args)
{
ModelStudent alex = null;
ModelStudent dan = new Sophomore();
ModelStudent matt = new ModelStudent(); // illegal
dan.doHomework();
}
}
- Here is a discussion on the differences between interfaces & abstract classes and when to use each
http://mindprod.com/jgloss/interfacevsabstract.html
Objective #7: Explain protected access control. NOT REALLY STRESSED ON AP EXAM.
- Use protected access rather than public access or private access with methods and/or instance fields that need to be directly accessible only to subclasses of a given class. A protected method or field cannot be used by client programmers.
- On the AP exam, protected access is only used in the Case Study. It will not be tested in the multiple choice questions.