Session 7 Lecture Notes for First Course in Java
Inheritance

(syllabus and calendar)

Summer 06 zip of commented examples

Fall 05 zip of lecture examples

Summer 05 zip of code with comments from class interaction

 

Examples for Homework #6

Inheritance

Non-default Constructors

Enforcing Inheritence by Call to Superconstructor

Overriding Methods

Dynamic Method Dispatch

Array with Dynamic Types

Abstract Class

final keyword has three levels


Quiz (with answers)


Optional Challenge

Examples for Homework #6

Homework #6: Write an abstract class called Animal that has at least one abstract method and one non-abstract method. Extend the abstract class in a non-abstract subclass that overrides the abstract method it inherits by implementing the abstract method. Your implementation must not be empty  { }. In other words, provide code in the implementation code block. Also override a non-abstract  method it inherits.

Overriding: see http://write-technical.com/126581/session7/index.htm#override
and http://java.sun.com/docs/books/tutorial/java/IandI/override.html

Abstract class: see See http://write-technical.com/126581/session7/index.htm#Abstract%20Class

Extending a class (subclassing)

class Person
{
   String name = "";
   int ssn = 0;
   Person(String name)
   {
      this.name = name;
   }
   Person(int ssn)
   {
      this.ssn = ssn;
   }
}
class Doctor extends Person
{
   Doctor(String name)
  {
      super(name);
   }

   Doctor(int socialSecurityNumber)
   {
      super(socialSecurityNumber);
   }
}
class PersonDemo
{
   public static void main(String[] args)
   {
      Doctor drwatson = new Doctor("Watson");
      drwatson.ssn = 001331234;
      System.out.println(drwatson.name + ": " + drwatson.ssn);

      Doctor drpepper = new Doctor(823556789);
      drpepper.name = "Soft Drink";
      System.out.println(drpepper.name + ": " + drpepper.ssn);
   }
}


Inheritance

We have seen multiple classes in the same compilation unit (file). Any number of class can be in the same java file, but it is generally a good idea to have only one. If the file has the main class, the file name must match the class with main.

Note: We can also put each class in each own file, as long as the class with main can see the other classes. Currently, we use the default package, so any class in the current directory is visible.

When you compile the class with main, the compiler also compiles any classes that main references.

Here, when we compile the class with main, we generate three class files. In our domain logic, the Triangle and the Rectangle classes are specializations of TwoDShape. The subclasses have special ways of calculating area.

Subclasses inherit from their single-inheritance superclass. The superclass encapsulates the general logic. The subclass adds specialization. The inheritence tree descends from the general (Object) to the specific (TwoDShape), to the even more specific (Triangle and Square). Thus, we can re-use shared, general code and only have to write the specialized differences on the subclasses.

Info for t1:
Triangle is isosceles
Width and height are 4.0 and 4.0
Area is 8.0

Info for t2:
Triangle is right
Width and height are 8.0 and 12.0
Area is 48.0

Info for r1:
Area is 9.0 and is this rectangle a square?: true

Two notes about inheritence:

Info for t1:
Triangle is isosceles
Width and height are 4.0 and 4.0
Area is 8.0

Info for t2:
Triangle is right
Width and height are 8.0 and 12.0
Area is 48.0

Inheritance and Non-default Constructors

Now let's set values with the constructor of the subclass instead of doing so in the class with main.

Info for t1:
Triangle is isosceles
Width and height are 4.0 and 4.0
Area is 8.0

Info for t2:
Triangle is right
Width and height are 8.0 and 12.0
Area is 48.0

Here, we add a constructor to the superclass, which can update functionality that subclasses do not know about.
Notes:

The following examples uses accessor methods, which are also called "getter" methods.

Info for t1:
Triangle is isosceles
Width and height are 4.0 and 4.0
Area is 8.0

Info for t2:
Triangle is right
Width and height are 8.0 and 12.0
Area is 48.0

Access a constructor of the superclass

Here, the subclass makes separate calls to each of the superclass constructors. The syntax for calling a superclass constructor is super(parameter_list). We care about the parameter list when calling a constructor because a constructor, like a method, can be overloaded.

Info for t1:
Triangle is right
Width and height are 8.0 and 12.0
Area is 48.0

Info for t2:
Triangle is right
Width and height are 8.0 and 12.0
Area is 48.0

Info for t3:
Triangle is isosceles
Width and height are 4.0 and 4.0
Area is 8.0

Access an instance variable of the superclass

Using super to access an instance variable of the superclass. Remember, the superclass does not know about its subclasses. Therefore, the changes made on the inherited member do not affect the superclasses copy of that member. Here, we use super.superclass_member in a manner analogous to using this.class_member, that is, to unhide a instance variable that has been hidden by a local variable.

i in A: 47
i in superclass: 1
i in subclass: 2
i in A: 47

Review: Access an constructor of the superclass

Let's review with a different class hierarchy.

Semi can carry 44000 pounds.
To go 252 miles semi needs 36.0 gallons of fuel.

Pickup can carry 2000 pounds.
To go 252 miles pickup needs 16.8 gallons of fuel.

Yet another class hierarchy, this time with three levels. There is no limit to the number of levels.

Info for t1:
Triangle is right
Width and height are 8.0 and 12.0
Color is Blue
Area is 48.0

Info for t2:
Triangle is isosceles
Width and height are 2.0 and 2.0
Color is Red
Area is 2.0


Enforcing Inheritence: superclass constructor called implicitly

The order of construction is determined by derivation. Java enforces that the superclass has priority.

If the superclass has instance variables that the constructor initializes, we can be certain that the subclass that inherits these instance variables will inherit them with the proper initialization.


Superclass Reference

The superclass X does not know about Y's instance variable b. However, a subclass can assign a reference of its superclass. In other words, a superclass reference can refer to a subclass object. Can  a subclass reference refer to a superclass object? No. Is this similar to the implicit cast of a primitive to a widening type?

The following program has a subclass that passes an object of its type to the superclass constructor. This supports basic code reuse. Is there a relationship between lines 64 and 22?

Info for t1:
Triangle is right
Width and height are 8.0 and 12.0
Area is 48.0

Info for t2:
Triangle is right
Width and height are 8.0 and 12.0
Area is 48.0


Method Overriding

Overloading is typically within the same class, and means different signatures for the same method name.
v
e
r
r
i
d
e
Overriding is how a subclass customizes the behavior it inherits, and means the same method signature but different implementation code.

Whereas method overloading is within the same class (horizontal), method overriding means the subclass method overrides the superclass method (vertical) it inherits.
Method overloading is polymorphism; method overriding is an exception to inheritance.

Suppose you the programmer who must write a subclass for a superclass. You see that one of the methods the subclass inherits from the superclass must have different behavior. A use case (http://en.wikipedia.org/wiki/Use_case) might be the calculateTax() method, which is different depending on the local nation, state, county, and/or city.

The following example illustrates overriding the inherited show() method.

The following demonstrates a method overloading. Do the signatures of the show method match?

To override a method, the subclass version must have the identical signature as the superclass version.
Otherwise, we have overloading that happens to occurs in the class that inherited the method.
So, in a sense, overloading, which is normally horizontal, can be vertical: the subclass can introduce a different signature to the method it inherits.
Overriding is always vertical.


Dynamic Method Dispatch Depends on Reference Type

At runtime, Java can determine which version of method to run according to which object that method is on.


Array of Dynamic Types

Method overriding used with the best practice of moving common logic up to the superclass. Shapes have areas, but each subclass can override the area method for its special circumstances. What are the contents of the array created in line 127? Does it violate the rule that an array must collect objects of solely ONE type?

object is triangle
Area is 48.0

object is rectangle
Area is 100.0

object is rectangle
Area is 40.0

object is triangle
Area is 24.5

object is generic
area() must be overridden
Area is 0.0


Abstract Class and Method Overriding

The previous program is a hack. Instead of printing a warning message, we should declare an abstract class. An abstract class is a common solution when we know the subclass is likely to override the superclass.

In general, provide an abstract class when you can provide only SOME of the implementation, and other developers will later provide additional customization of your code. Use cases (http://en.wikipedia.org/wiki/Use_case) might be:

An abstract class cannot be instantiated. Instead, an abstract class can provide partial implementation. A non-abstract subclass typically overrides one or more methods of the abstract superclass. The non-abstract subclass can be instantiated.

object is triangle
Area is 48.0

object is rectangle
Area is 100.0

object is rectangle
Area is 40.0

object is triangle
Area is 24.5


Avoiding Inheritance with the keyword final

The keyword final has three levels of use in Java: variable, method, class.

Final can be used with a variable to make it a constant:

final int BOILING_POINT = 100;

The following example uses a standard convention for error messages. The API could advise user programmers to use the string  constants. The associated integers can be changed between product releases without breaking code.

A method can be declared final. That means it cannot be overridden.

A class be declared final. That means that not only are its methods final, but the class cannot be extended by a subclass or even inherited by a subclass. A final class is one way to provide logic that is uniform throughout a large project involving many programmers.


Quiz (with answers)

  1. Class B extends A. Both have a method called makeApplesauce. In B, this method takes an integer argument. In A, this method takes a double argument. Is the method overloaded, overridden, both, or neither?

    Overloaded even though it is in a subclass. The method that overrides another method must have exactly the same signature as the method it overrides.
     
  2. When I explicitly call the constructor of class B, what is implicitly called?

    The constructor of the superclass.
     
  3. Referring to the answer of Question 2, why is this the way it is?

    To enforce inheritance. For example, to initialize any inherited instance variables.
     
  4. What does the word final mean for the following?:
  1. Referring to Question 4, which of the three levels relates to:
  1. In what sense is an abstract class abstract?

    At least one method is not implemented (no code block) and consists solely of a statement that is a signature declaration
     
  2. In what sense can an abstract class be something other than fully abstract?

    It can have one or more method implementations (code blocks, whether empty or not). We will see that an interface does not allow for any implementation inside of itself.
     
  3. Does a subclass inherit the constructors of its superclass?

    No, but it can call the constructor that belongs to its immediate superclass.
     
  4. Using the keyword super, what can the current class gain access to?

    The constructor of the immediate superclass.
     
  5. Java does not allow the syntax of super.super   
    Why not? What possible problems could that cause?

    Confusion. This way, the options are limited and simple.
     
  6. By default, there is a constructor that takes no argument.

Optional Extra Challenge

Experiment with Swing