Programming Tutorials Browser Tutorials Articles Struts Tutorials Hibernate Tutorials

  Tutorial: Reveal the magic behind subtype polymorphism - JavaWorld April 2001

Reveal the magic behind subtype polymorphism - JavaWorld April 2001

Tutorial Details:

Reveal the magic behind subtype polymorphism
Reveal the magic behind subtype polymorphism
By: By Wm. Paul Rogers
Behold polymorphism from a type-oriented point of view
he word polymorphism comes from the Greek for "many forms." Most Java developers associate the term with an object's ability to magically execute correct method behavior at appropriate points in a program. However, that implementation-oriented view leads to images of wizardry, rather than an understanding of fundamental concepts.
Polymorphism in Java is invariably subtype polymorphism. Closely examining the mechanisms that generate that variety of polymorphic behavior requires that we discard our usual implementation concerns and think in terms of type. This article investigates a type-oriented perspective of objects, and how that perspective separates what behavior an object can express from how the object actually expresses that behavior. By freeing our concept of polymorphism from the implementation hierarchy, we also discover how Java interfaces facilitate polymorphic behavior across groups of objects that share no implementation code at all.
Quattro polymorphi
Polymorphism is a broad object-oriented term. Though we usually equate the general concept with the subtype variety, there are actually four different kinds of polymorphism. Before we examine subtype polymorphism in detail, the following section presents a general overview of polymorphism in object-oriented languages.
Luca Cardelli and Peter Wegner, authors of "On Understanding Types, Data Abstraction, and Polymorphism," (see Resources for link to article) divide polymorphism into two major categories -- ad hoc and universal -- and four varieties: coercion, overloading, parametric, and inclusion. The classification structure is:
|-- coercion
|-- ad hoc --|
|-- overloading
polymorphism --|
|-- parametric
|-- universal --|
|-- inclusion
In that general scheme, polymorphism represents an entity's capacity to have multiple forms. Universal polymorphism refers to a uniformity of type structure, in which the polymorphism acts over an infinite number of types that have a common feature. The less structured ad hoc polymorphism acts over a finite number of possibly unrelated types. The four varieties may be described as:
Coercion: a single abstraction serves several types through implicit type conversion
Overloading: a single identifier denotes several abstractions
Parametric: an abstraction operates uniformly across different types
Inclusion: an abstraction operates through an inclusion relation
I will briefly discuss each variety before turning specifically to subtype polymorphism.
Coercion
Coercion represents implicit parameter type conversion to the type expected by a method or an operator, thereby avoiding type errors. For the following expressions, the compiler must determine whether an appropriate binary + operator exists for the types of operands:
2.0 + 2.0
2.0 + 2
2.0 + "2"
The first expression adds two double operands; the Java language specifically defines such an operator.
However, the second expression adds a double and an int ; Java does not define an operator that accepts those operand types. Fortunately, the compiler implicitly converts the second operand to double and uses the operator defined for two double operands. That is tremendously convenient for the developer; without the implicit conversion, a compile-time error would result or the programmer would have to explicitly cast the int to double .
The third expression adds a double and a String . Once again, the Java language does not define such an operator. So the compiler coerces the double operand to a String , and the plus operator performs string concatenation.
Coercion also occurs at method invocation. Suppose class Derived extends class Base , and class C has a method with signature m(Base) . For the method invocation in the code below, the compiler implicitly converts the derived reference variable, which has type Derived , to the Base type prescribed by the method signature. That implicit conversion allows the m(Base) method's implementation code to use only the type operations defined by Base :
C c = new C();
Derived derived = new Derived();
c.m( derived );
Again, implicit coercion during method invocation obviates a cumbersome type cast or an unnecessary compile-time error. Of course, the compiler still verifies that all type conversions conform to the defined type hierarchy.
Overloading
Overloading permits the use of the same operator or method name to denote multiple, distinct program meanings. The + operator used in the previous section exhibited two forms: one for adding double operands, one for concatenating String objects. Other forms exist for adding two integers, two longs, and so forth. We call the operator overloaded and rely on the compiler to select the appropriate functionality based on program context. As previously noted, if necessary, the compiler implicitly converts the operand types to match the operator's exact signature. Though Java specifies certain overloaded operators, it does not support user-defined overloading of operators.
Java does permit user-defined overloading of method names. A class may possess multiple methods with the same name, provided that the method signatures are distinct. That means either the number of parameters must differ or at least one parameter position must have a different type. Unique signatures allow the compiler to distinguish between methods that have the same name. The compiler mangles the method names using the unique signatures, effectively creating unique names. In light of that, any apparent polymorphic behavior evaporates upon closer inspection.
Both coercion and overloading are classified as ad hoc because each provides polymorphic behavior only in a limited sense. Though they fall under a broad definition of polymorphism, these varieties are primarily developer conveniences. Coercion obviates cumbersome explicit type casts or unnecessary compiler type errors. Overloading, on the other hand, provides syntactic sugar, allowing a developer to use the same name for distinct methods.
Parametric
Parametric polymorphism allows the use of a single abstraction across many types. For example, a List abstraction, representing a list of homogeneous objects, could be provided as a generic module. You would reuse the abstraction by specifying the types of objects contained in the list. Since the parameterized type can be any user-defined data type, there are a potentially infinite number of uses for the generic abstraction, making this arguably the most powerful type of polymorphism.
At first glance, the above List abstraction may seem to be the utility of the class java.util.List . However, Java does not support true parametric polymorphism in a type-safe manner, which is why java.util.List and java.util 's other collection classes are written in terms of the primordial Java class, java.lang.Object . (See my article " A Primordial Interface? " for more details.) Java's single-rooted implementation inheritance offers a partial solution, but not the true power of parametric polymorphism. Eric Allen's excellent article, " Behold the Power of Parametric Polymorphism ," describes the need for generic types in Java and the proposals to address Sun's Java Specification Request #000014, "Add Generic Types to the Java Programming Language." (See Resources for a link.)
Inclusion
Inclusion polymorphism achieves polymorphic behavior through an inclusion relation between types or sets of values. For many object-oriented languages, including Java, the inclusion relation is a subtype relation. So in Java, inclusion polymorphism is subtype polymorphism.
As noted earlier, when Java developers generically refer to polymorphism, they invariably mean subtype polymorphism. Gaining a solid appreciation of subtype polymorphism's power requires viewing the mechanisms yielding polymorphic behavior from a type-oriented perspective. The rest of this article examines that perspective closely. For brevity and clarity, I use the term polymorphism to mean subtype polymorphism.
Type-oriented view
The UML class diagram in Figure 1 shows the simple type and class hierarchy used to illustrate the mechanics of polymorphism. The model depicts five types, four classes, and one interface. Although the model is called a class diagram, I think of it as a type diagram. As detailed in " Thanks Type and Gentle Class ," every Java class and interface declares a user-defined data type. So from an implementation-independent view (i.e., a type-oriented view) each of the five rectangles in the figure represents a type. From an implementation point of view, four of those types are defined using class constructs, and one is defined using an interface.
Figure 1. UML class diagram for the example code
The following code defines and implements each user-defined data type. I purposely keep the implementation as simple as possible:
/* Base.java */
public class Base
{
public String m1()
{
return "Base.m1()";
}
public String m2( String s )
{
return "Base.m2( " + s + " )";
}
}
/* IType.java */
interface IType
{
String m2( String s );
String m3();
}
/* Derived.java */
public class Derived
extends Base
implements IType
{
public String m1()
{
return "Derived.m1()";
}
public String m3()
{
return "Derived.m3()";
}
}
/* Derived2.java */
public class Derived2
extends Derived
{
public String m2( String s )
{
return "Derived2.m2( " + s + " )";
}
public String m4()
{
return "Derived2.m4()";
}
}
/* Separate.java */
public class Separate
implements IType
{
public String m1()
{
return "Separate.m1()";
}
public String m2( String s )
{
return "Separate.m2( " + s + " )";
}
public String m3()
{
return "Separate.m3()";
}
}
Using these type declarations and class definitions, Figure 2 depicts a conceptual view of the Java statemen


 

Read Tutorial at: Click here to view the tutorial

Rate Tutorial:
Reveal the magic behind subtype polymorphism - JavaWorld April 2001

View Tutorial:
Reveal the magic behind subtype polymorphism - JavaWorld April 2001

Related Tutorials:

XML messaging, Part 3
XML messaging, Part 3
 
Object-oriented language basics, Part 7
Object-oriented language basics, Part 7
 
Reflection vs. code generation
Reflection vs. code generation
 
Diagnose common runtime problems with hprof
Diagnose common runtime problems with hprof
 
A birds-eye view of Web services
A birds-eye view of Web services
 
Check out three collections libraries
Check out three collections libraries
 
TRMI
TRMI
 
Make the Java-Oracle9i connection
Make the Java-Oracle9i connection
 
Test email components in your software
Test email components in your software
 
Filtering and Transforming Digital Images
Filtering and Transforming Digital Images In this Issue Welcome to the Core Java Technologies Tech Tips for April 7, 2004. Here you\'ll get tips on using core Java technologies and APIs, such as those in Java 2 Platform, Standard Edition (J2SE).
 
Wakeonlan
What is wakeonlan? wakeonlan is a small OS independent java program that sends 'magic packets' to wake-on-lan enabled ethernet adapters and motherboards in order to switch on the called machine.It runs on every machine with an installed 1.4 java runtime.
 
J2EE application performance optimization
J2EE application performance optimization How to extract maximum performance from your J2EE Web applications In this article, Rahul Kuchhal demonstrates how to identify and resolve bottlenecks in a J2EE application. This article covers all the step
 
Java Mime Magic Library
Java Mime Magic Library jMimeMagic is a Java library for determining the MIME type of files or streams.
 
FreeMarker FreeMarker 2.3.1 an open-source HTML template engine.
FreeMarker provides an easy way to get data from Java servlets into Web pages, and helps you keep graphic design separate from application logic. To use it, you encapsulate HTML in templates.
 
J2J - Java to JavaScript integration.
It is a development tool lets you to integrate Java classes and JavaScript within your HTML pages. The main idea behind this product is how to call methods of Java classes right from JavaScript functions.
 
alaJSP JSP-similar processor
It is yet another servlet based preprocessor. The common idea behind that line of the products (see ColdCafe site) is splitting static HTML presentation which done by designers and dynamic proceed developed by programmers.
 
Hibernate simplifies inheritance mapping.
Learn three easy-to-implement strategies to map class hierarchies. Hibernate is an object-relational mapping and persistence framework that provides a lot of advanced features, ranging from introspection to polymorphism and inheritance mapping.
 
What is Persistence Framework?
What is Persistence Framework? What is Persistence Framework? A persistence framework moves the program data in its most natural form (in memory objects) to and from a permanent data store the database. The persistence framework manages the
 
Core Java Interview Questions!
Core Java Interview Questions! Core Java Interview Questions Question: What is transient variable? Answer: Transient variable can't be serialize. For example if a variable is declared as transient in a Serializable class and the class is written
 
one-jar
One-JAR is a simple solution to a vexing problem in Java: how to distribute an application as a single jar-file, when it depends on multiple other jar-files. One-JAR uses a custom classloader to discover library jar files inside the main jar.
 
Site navigation
 

 

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright © 2006. All rights reserved.