Session 7 Lecture Notes for First Course in Java

25-JULY-2005


(syllabus and calendar)

 

Workaround for truncation of a double

Inheritance from the superclass

The keyword super

Multilevel hierarchy

Constructors: priority of the ancestors

Using super to overcome method overriding

Dynamic Method Dispatch

Abstract Classes

final with Inheritance (three levels for this keyword)

The Object Class


Interfaces


Quiz

Homework Assignment


Workaround for truncation of a double

Output:

Dimensions: 1.23 x 2.34 x 3.45.
Purchased: 10 cubic inches of gold.
Machinist labor: 32.25 hours.
Cost $1262.


Inheritance from the superclass

A subclass inherits from its superclass.

 

The keyword super

Let us look at two uses for the keyword super.

Calling the constructor of the superclass

If you call super() at the beginning of a subclass constructor, you are actually calling the constructor of the superclass.
This example uses super() to gain access to superclass members, and it also adds its own member, weight.

Accessing superclass members

The keyword super also gives you access to properties and methods of the superclass. (There is no super.super.)

Multilevel hierarchy

A superclass can have multiple subclasses. Each subclass can only have one superclass. This is called single inheritance and is one of the differences between Java and C++. Each subclass can have multiple subclasses. Single inheritance is a limitation that helps human beings avoid confusion. We will see later that interfaces are a safe workaround for this limitation.

Constructors: priority of the ancestors

In many cultures, when it comes to offering food, the ancestors (or the gods) have priority over living people, and the elders have priority over the younger people.
Java is like that too because the constructor of the superclass has priority over the constructor of the subclass.
This observance of the hierarchy ensures that inheritance occurs before any subsequence local specialization.

The output is:

Note that execution follows the top-down order of the class hierarchy even though the compiler had to parse a source file that put a subclass of a subclass before the highest superclass. What would happen if constructors where not called "top-down" but rather "bottom-up"?

Using super to overcome method overriding

Just as a local variable in an inner code block hides a variable of the same name in an outer code block, so a local method overrides and hides a method of the same name in a superclass.

Automatic method overriding is a useful default to overcome what some programmers call a "namespace collision". However, what if you want to use the superclass implementation of a method with the same name as the current class method? The answer is use the keyword  super  because it gives you access to all the members of the superclass.

Dynamic Method Dispatch

Dynamic method dispatch supports runtime polymorphism by allowing subclasses to override methods while also allowing the superclass to define a general form for the overridden methods..

Suppose you have one server machine in Madrid and three client machines: one in Osaka, one in San Francisco, and one in Bangalore.
Each local area wants to have its own way of implementing certain logic, but the central office does want to impose some kind of standard.
One solution would be to have a superclass that specifies a named method, but allow the localities to call their local version.
In this case, we have inheritance from a superclass along with polymorphism of the method.


What determines which form of the polymorphism to execute? A runtime event: the assignment of a subclass reference to the superclass reference. In effect, the superclass acts as if it knows the subclass implementation, even though it cannot. We say that the subclass method overrides the superclass method by virtue of dynamic dispatch. In other words, at runtime the local subclass calls calls a reference of the superclass that holds the object of a subclass.

One possible scenario for this sort of architecture would be that an architect at headquarters in Madrid writes the Dispatch class for the overall business flow, but lets each local office write its own class for business details. Amsterdam writes class A, Bangalore writes class B, and Copenhagen writes class C. Each local office adapts its class to the local taxes and business environment. 

For a less trivial example, consider shapes that derive from a general (almost abstract) shape.

Abstract Classes

We said that the previous example defined a general shape that was "almost" abstract.
In the previous example, we had an area method for the superclass, but it could not have any definition that was common to both its subclasses.
Perhaps there is a more elegant way to deal with truly abstract methods without pretending they are more definite than they actually are, and without having to override something that doesn't belong.
Java supports the concept of an abstract class with the keyword abstract.
An abstract class cannot generate objects (instances). Instead, it is the responsibility of the subclass(es) to instantiate the abstract class.

Now that we understand the syntax, let us re-implement the area calculation from an general superclass. This time, the area method of the superclass can be appropriately abstract. Let's walk through the execution step-by-step.

 

Abstraction: Conceptual Information

http://java.sun.com/docs/books/tutorial/java/javaOO/abstract.html

Sometimes, a class that you define represents an abstract concept and, as such, should not be instantiated. Take, for example, food in the real world. Have you ever seen an instance of food? No. What you see instead are instances of carrot, apple, and chocolate. Food represents the abstract concept of things that we all can eat. Because food is so generic, it doesn't make sense for an instance of food to exist. Instead of a food object, we want an apple object or an apple pie object.

Similarly in object-oriented programming, you might want to model an abstract concept without being able to create an instance of it. For example, the Number class in the java.lang package represents the abstract concept of numbers. It makes sense to model numbers in a program, but it doesn't make sense to create a generic number object. Instead, the Number class makes sense only as a superclass to classes like Integer and Float, both of which implement specific kinds of numbers.

Another example might be library materials, such as books, magazines, CDs, and videos. You might have an abstract class, LibraryItem, and make specific types of library items be subclasses of LibraryItem. However, you might not have any use for a LibraryItem object, because any physical library item is either a book, magazine, CD, or video, and you want to handle it appropriately. What would be the purpose of the abstract LibraryItem class? To specify the attributes and behavior that are common to all library items. Books, magazines, CDs, and videos might all have attributes such as title, card_catalog_number, replacement_price and isCheckedOut. These library items might all have behavior such as checkOut(), checkIn(), searchIfLost(), repair(), and replace().

A class such as Number, which represents an abstract concept and should not be instantiated, is called an abstract class. An abstract class is a class that can only be subclassed-- it cannot be instantiated.

To declare that your class is an abstract class, use the keyword abstract before the class keyword in your class declaration:

abstract class Number {
    . . .
}

If you attempt to instantiate an abstract class, the compiler displays an error similar to the following and refuses to compile your program:

AbstractTest.java:6: class AbstractTest is an abstract class.
It can't be instantiated.
        new AbstractTest();
        ^
1 error

Abstract Methods

An abstract class can contain abstract methods, that is, methods with no implementation. In this way, an abstract class can define a complete programming interface, thereby providing its subclasses with the method declarations for all of the methods necessary to implement that programming interface. However, the abstract class can leave some or all of the implementation details of those methods up to its subclasses.

Let's look at an example of when you might want to create an abstract class with an abstract method in it. In an object-oriented drawing application, you can draw circles, rectangles, lines, Bezier curves, and so on.

Each of these graphic objects share certain

You can take advantage of these similarities and declare them all to inherit from the same parent object--GraphicObject.

 

 

 

However, the graphic objects are also substantially different in many ways: drawing a circle is quite different from drawing a rectangle. The graphics objects cannot share these types of states or behavior. On the other hand, all GraphicObjects must know how to draw themselves; they differ merely in how they are drawn. Objects of the subclasses have specialized implementation. This is a perfect situation for an abstract superclass.

First you declare an abstract class, GraphicObject, to provide member variables and methods that are shared by all subclasses, such as the current position and the moveTo() method. GraphicObject also declares abstract methods for methods, such as draw(), that need to be implemented by all subclasses, but are implemented in entirely different ways (no default implementation in the superclass makes sense). The GraphicObject class would look something like this:

abstract class GraphicObject {
    int x, y;
    . . .
    void moveTo(int newX, int newY) {
        . . .
    }
    abstract void draw();
}

Each non-abstract subclass of GraphicObject, such as Circle and Rectangle, would have to provide an implementation for the draw() method.

class Circle extends GraphicObject {
    void draw() {
        . . .
    }
}
class Rectangle extends GraphicObject {
    void draw() {
        . . .
    }
}

An abstract class is not required to have an abstract method in it. However, any class that has an abstract method in it (or that does not provide an implementation for any abstract methods declared in its superclasses) must be declared as an abstract class.


final with Inheritance

One of the key benefits of an object-oriented language is code reuse. Here we seem something different yet similar. The keyword final is reused within three levels of the object-oriented language. The keyword final has a similar meaning at three levels:

http://java.sun.com/docs/books/tutorial/java/javaOO/final.html

Writing Final Classes and Methods

You can declare that your class is final, that is, that your class cannot be subclassed. There are (at least) two reasons why you might want to do this: to increase system security by preventing system subversion, and for reasons of good object-oriented design.

Security:

One mechanism that hackers use to subvert systems is to create a subclass of a class and then substitute their class for the original.
[Trojan Horse]  The subclass looks and feels like the original class but does vastly different things, possibly causing damage or getting into private information. To prevent this kind of subversion, you can declare your class to be final and thereby prevent any subclasses from being created. The String class in the java.lang package is a final class for just this reason. This class is so vital to the operation of the compiler and the interpreter that the Java system must guarantee that whenever a method or object uses a String it gets exactly a java.lang.String and not some other string. This ensures that all strings have no strange, inconsistent, undesirable, or unpredictable properties.

If you try to compile a subclass of a final class, the compiler prints an error message and refuses to compile your program. In addition, the bytecode verifier ensures that the subversion is not taking place at the bytecode level. It does this by checking to make sure that a class is not a subclass of a final class.

Design:

You can declare a class as final for object-oriented design reasons. Your class is "perfect" and should have no subclasses. [Perhaps headquarters wants to impose an architecture, standard, or work flow on all the local offices.] 

To specify that your class is final, use the keyword final before the class keyword in your class declaration.

For example, if you wanted to declare your (perfect) ChessAlgorithm class as final, its declaration should look like this:

final class ChessAlgorithm {
    . . .
}

Any subsequent attempts to subclass ChessAlgorithm will result in a compiler error such as the following:

Chess.java:6: Can't subclass final classes: class ChessAlgorithm
class BetterChessAlgorithm extends ChessAlgorithm {
      ^
1 error

Final Methods

Does creating a final class seem heavy-handed for your needs? Do you really just want to protect some of your class's methods from being overridden? You can use the final keyword in a method declaration to indicate to the compiler that the method cannot be overridden by subclasses. As just shown, the Object class does this; some of its methods are final and some are not.

You might wish to make a method final if it has an implementation that should not be changed and it is critical to the consistent state of the object. For example, instead of making [ALL OF] your ChessAlgorithm class final, [only] make the nextMove method final:

class ChessAlgorithm {
    . . .
    final void nextMove(ChessPiece pieceMoved,
                        BoardLocation newLocation)
    {
        ...
    }
    . . .
}

The Object Class

Because all objects inherit from the class java.lang.Object, all objects have access to certain methods.
Among these methods are the following:

protected Object clone() The method is visible to the class, its subclasses, and its package, but not public to the world
public final Class getClass() The method cannot be overridden. This guarantees that it will work as expected. This is important because the functionality is fundamental and basic.
public String toString() Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.  [Customize for your audience.]

 

 

 

 

 


Interfaces

In the Java core APIs, some items appear in italics. These are interfaces rather than classes.

The Serializable interface indicates that an implementing class is serializable. To serialize a class (or an object) is to make it possible to transmit the class (or an object) over a network. Imagine a serial port (or socket) that is getting a stream of data over the internet. The data must be in a format so that it can be read back into an object. Serialization might be what Scotty does in Star-Trek when he "beams" Captain Kirk down to a planet. Kirk becomes a series of light beams that, presumably, contain the information necessary to reconstitute Kirk in the new environment. Captain James Kirk implements the Beamable interface.

A FAX is a serialization of an image of a page of paper. The piece of paper is represented by an image that is a "bitmap". The telephone line transmits each bit in a series, perhaps with a high tone for a black dot and a low tone for white dot. The receiving fax machine de-serializes the song of the phone line into a reproduction of the original image of piece of paper.

Perhaps your business logic only allows certain documents to be faxable.

Just as a class is a template (cookie-cutter) for making objects, so an interface is a template for making classes.
An interface is a contract that the implementing class fulfills.
An interface is a bit like a functional specification about WHAT a class does, not HOW it does it.
One way to understand an interface is as a requirement of capability rather than inherited functionality.
If something has a name such as the following, it is more likely to be an interface than a class: Beamable, Faxable, Transportable, Printable, Comparable, Taxable, Mutable.
It is a good idea to put a capital "I" at the front of the name: IBeamable, IFaxable, ITransportable, IPrintable.

Whereas a class can only inherit from one superclass (even if the class hierarchy creates a vertical chain), a class can implement multiple interfaces.
Interfaces provide an alternate route to functionality without breaking the principle of single inheritence.
An interface is a safe way to provide something similar to multiple inheritance. Because there is no implementation in an interface, there is no danger of confusing which branch of inheritance provides the behavior: there is only branch of inheritance to the superclass.

Defining an interface

When you define an interface, you specify methods and/or properties, but do not fill in method code blocks, that is, you do not implement.

interface MyInterface 
{
  void myMethodX(double myParameter);

  boolean myMethodY(); 

} 

Implementing an interface

The interface cannot implement the classes it specifies. No implementation is allowed at the interface level.
A class that implements an interface must implement all the class members specified in the interface.
The compiler checks for methods that match the signature given in the interface definition.
The implementation can be blocks of empty code, but at least in form each class must have an implementation.

Abstract classes versus Interfaces

  CLASS ABSTRACT CLASS INTERFACE
Definition: A class must be complete, at least in form, or the compiler does not compile. Default behavior is not required but is generally the case. An incomplete specification, which can provide default behavior. A specification of behavior (methods) without any implementation (no default behavior) and no fields except for constants that are static and final. No method bodies. In effect, an interface is an application programming interface (API) with implicitly public methods.
Inheritence: A class can extend only ONE class. A class inherits from its parent class (single inheritence), but can implement multiple interfaces. A class can extend only ONE class, whether it is abstract or not.

The class that extends its abstract class parent can implement some methods and declare other methods to be abstract (for still later implementation)
A interface can be implemented by zero, one, or more classes.

An interface can extend zero, one, or more superinterfaces.

The class that implements an interface must implement all interface methods and any superinterface methods.

When to create: Create a class if you know the default behavior you want, and if you do not need to provide a specification for other programmers. Create an abstract class if you want to partially implement a class now, and have you or others do additional implementation later. 
Subclasses can benefit from the default implementation of (some) methods of the abstract class.

Flexibility: An abstract class allows you to add nonabstract methods without breaking classes that extend the abstract classes.

Create an interface if  (1) you want to define methods (no current implementation at all) that you, or others, will later implement, and (2) you want a workaround for the absence of "multiple inherence" (C++ "mixins).
 
Create an interface if you want a convenient way for any class to have access to a set of constants. In this case, your interface would not contain any methods.
Create an interface if you want a commitment to stability: because an interface is an API, you cannot add any new methods without breaking any classes that implement the previous version.

 

Note: An interface does not necessarily prescribe the implementation of methods. For example, consider this interface, which acts like a flag or notification of a capability: the capability of being copied.

http://java.sun.com/j2se/1.4.1/docs/api/java/lang/Cloneable.html
public interface Cloneable

A class implements the Cloneable interface to indicate to the Object.clone() method
that it is legal for that method to make a field-for-field copy of instances of that class.

What if you only want to implement some of the classes in the interface?
In this case, the implementing class must be declared an abstract class with the modifier abstract.

abstract class MyPartialImplementationClass implements YourInterface {
// implementation code

Extending an interface

You already know that you can write a subclass that inherits from its superclass by using the keyword extends.
Similarly, you can write an interface that inherits from an existing interface, and the keyword remains extends.
Even when we inherit from a super-interface, no sub-interface can engage in implementation.

**************

http://java.sun.com/docs/books/tutorial/java/concepts/interface.html

What Is an Interface?

In English, an interface is a device or a system that unrelated entities use to interact. According to this definition, a remote control is an interface between you and a television set, the English language is an interface between two people, and the protocol of behavior enforced in the military is the interface between people of different ranks. Within the Java programming language, an interface(in the glossary) is a device that unrelated objects use to interact with each other. An interface is probably most analogous to a protocol (an agreed on behavior). In fact, other object-oriented languages have the functionality of interfaces, but they call their interfaces protocols.

The bicycle class and its class hierarchy defines what a bicycle can and cannot do in terms of its "bicycleness." But bicycles interact with the world on other terms. For example, a bicycle in a store could be managed by an inventory program. An inventory program doesn't care what class of items it manages as long as each item provides certain information, such as price and tracking number. Instead of forcing class relationships on otherwise unrelated items, the inventory program sets up a protocol of communication. This protocol comes in the form of a set of constant and method definitions contained within an interface. The inventory interface would define, but not implement, methods that set and get the retail price, assign a tracking number, and so on.

To work in the inventory program, the bicycle class must agree to this protocol by implementing the interface. When a class implements an interface, the class agrees to implement all the methods defined in the interface. Thus, the bicycle class would provide the implementations for the methods that set and get retail price, assign a tracking number, and so on.

You use an interface to define a protocol of behavior that can be implemented by any class anywhere in the class hierarchy. Interfaces are useful for the following:

Creating and Implementing Interfaces

http://java.sun.com/docs/books/tutorial/java/interpack/interfaces.html

The Java programming language supports interfaces that you use to define a protocol of behavior that can be implemented by any class anywhere in the class hierarchy.

What Is an Interface?
This section defines the term "interface," shows you an example of an interface and how to use it, and talks about why you may need interfaces in your programs.
Defining an Interface
Defining an interface is similar to creating a new class. An interface definition has two components: the interface declaration and the interface body.
interfaceDeclaration {
    interfaceBody
}

The interfaceDeclaration declares various attributes about the interface such as its name and whether it extends another interface. The interfaceBody contains the constant and method declarations within the interface.

Implementing an Interface
To use an interface, you write a class that implements the interface. When a class claims to implement an interface, the class is claiming that it provides a method implementation for all of the methods declared within the interface (and its superinterfaces).
Using an Interface as a Type
When you define a new interface you are in essence defining a new reference data type. You can use interface names anywhere you'd use any other type name: variable declarations, method parameters and so on.
Warning! Interfaces Cannot Grow
If you ship public interfaces to other programmers, here's a limitation of interfaces that you should be aware of: Interfaces cannot grow.
Summary
A summary of important concepts covered in this section.

http://java.sun.com/docs/books/tutorial/java/interpack/QandE/interfaces-answers.html

Question 1: What methods would a class that implements the java.util.Iterator interface have to implement?
Answer 1: next, hasNext, and remove

Question 2: What is wrong with the following interface?

public interface SomethingIsWrong {
    public void aMethod(int aValue) {
        System.out.println("Hi Mom");
    }
}

Answer 2: It has a method implementation in it. It should just have a declaration.

Question 3: Fix the interface in Question 2.
Answer 3:

public interface SomethingIsWrong {
    public void aMethod(int aValue);
}

Question 4: Is the following interface valid?

public interface Marker {
}

Answer 4: Yes. Methods are not required. Empty interfaces can be used as types and to mark classes without requiring any particular method implementations. For an example of a useful empty interface, see java.io.Serializable.


Quiz

  1. The keyword final can apply at three levels of scope. What are they?
  2. What is the difference between the keyword super and the keyword this?
  3. What is the difference between method overloading and method overriding?
  4. What is the order in which constructor calls are executed and why is it in this order?
  5. How many direct superclasses can a subclass have?
  6. What is dynamic method dispatch?
  7. What is an abstract class?
  8. In what way is using an abstract class different from using dynamic method dispatch?
  9. What is the difference between an abstract class and an interface in regard to inheritance?
  10. What is the difference between an abstract class and an interface in regard to implementation?

Homework Assignment

Write a program that extends an abstract class and that implements an interface.
If possible, use an abstract class that provides SOME implementation.
If possible, use a scenario in which it makes sense that the abstract class provides some implementation, and it also makes sense that the interface does not provide any implementation.
For example:
abstract class Pizza might not implement any recipe-related methods and yet implement pricing method: double calculateTotalPrice(menuPrice + anySalesTax). Therefore the MyPizza class might extend Pizza by specifying ingredients. MyPizza might also implement a Taxable interface that makes sure that you check whether the city, county, or state requires sales tax.

Another example:
abstract class NetFlixCustomer does a partial implementation of FilmCategory (comedy, drama) but allows for additional genres to be added later. An interface might require checking how many times the customer claims the post office lost the DVD that he or she mailed back to NetFlix but that never arrived at NetFlix. Each NetFlix warehouse might be allowed to implement that interface in a different way, such as charge a fee, charge a fee only if a second DVD is lost, reduce the number of films that can be out at any time to 1, or ignore the issue.

Another example:
The Shippable interface specifies a calculateShipping(weightOfProduct) method with a return type of double.
The Store abstract class specifies some methods and implements some methods:
takePhoneOrder()
takeFaxOrder()
takeEmailOrder()
The MusicStore class extends Store and implements calculateShipping for orders that are shipped but also permits customers to walk in and buy orders without having to pay shipping.