25-JULY-2005 (syllabus and calendar)
|
Workaround for truncation
of a double Inheritance from the superclass Constructors: priority of the ancestors Using super to overcome method overriding final with Inheritance (three levels for this keyword) |
Output:
Dimensions: 1.23 x 2.34 x 3.45.
Purchased: 10 cubic inches of gold.
Machinist labor: 32.25 hours.
Cost $1262.
A subclass inherits from its superclass.
Let us look at two uses for the keyword super.
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.
The keyword super also gives you access to properties and methods of the superclass. (There is no super.super.)
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.
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"?
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 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.
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.
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 thejava.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, theNumber
class makes sense only as a superclass to classes likeInteger
andFloat
, 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 theclass
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
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
- states, such as position, bounding box
- and behavior, such as moveTo(), resize(), draw().
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
GraphicObject
s 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 asdraw()
, that need to be implemented by all subclasses, but are implemented in entirely different ways (no default implementation in the superclass makes sense). TheGraphicObject
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 asCircle
andRectangle
, would have to provide an implementation for thedraw()
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.
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
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. TheString
class in thejava.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 aString
it gets exactly ajava.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 theclass
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
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, theObject
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 thenextMove
method final:class ChessAlgorithm { . . . final void nextMove(ChessPiece pieceMoved, BoardLocation newLocation) { ... } . . . }
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.] |
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.
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(); }
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.
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
A class implements the |
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
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
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:
- Capturing similarities among unrelated classes without artificially forcing a class relationship.
- Declaring methods that one or more classes are expected to implement.
- Revealing an object's programming interface without revealing its class.
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.
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.