Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Polymorphism in Java SE?

Reply
Thread Tools

Polymorphism in Java SE?

 
 
Stefan Ram
Guest
Posts: n/a
 
      12-22-2007
For teaching purposes, I'd like to know a Java-SE method
that returns an object whose class is only known at runtime
and can be shown to have at least two possibly values by
running a small program.

It would be best if this would be a static method that can
be called without any preparation.

For example, it would be great, if Java SE had an »input« method,
which returned »java.lang.Integer« or »java.lang.String«
depending on the text typed in the console.

Then I could write:

public class Main
{
public static void main
( final java.lang.String[] args )
{
java.lang.System.out.println
( java.lang.System.in.input().getClass() ); }}

Which would print »java.lang.Integer« (when one
enters »123«) or »java.lang.String« (when one enters »abc«).

However, I am not aware of such a method.

The usual approach is to put objects of different classes
into a heterogeneous container, then reading them in again,
and - surprise! - get objects of different classes.

I wonder, if it can get any simpler, without a container,
without preparation.

A near miss is the field »System.in«, which indeed contains an
object of a proper /subtype/ of the field's type. So it is
somewhat polymorphic. You do not know the actual type until
run-time. It is only boring insofar as it is always the same
subtype.

Possibly, somewhere in the huge Java-SE API there is a little
known field or method I could use.

 
Reply With Quote
 
 
 
 
Mark Rafn
Guest
Posts: n/a
 
      12-22-2007
Stefan Ram <(E-Mail Removed)-berlin.de> wrote:
> For teaching purposes, I'd like to know a Java-SE method
> that returns an object whose class is only known at runtime
> and can be shown to have at least two possibly values by
> running a small program.


Doesn't this describe just about any factory method? This seems to be pretty
fundamental to the point of interfaces, and you should be able to find or
create dozens of examples.

> It would be best if this would be a static method that can
> be called without any preparation.


Calendar.getInstance returns a Calendar object that's actually a subclass, for
instance. Swing's UIManager.getLookAndFeel() will return a different
LookAndFeel subclass depending on platform and settings.

In both cases (and most useful cases of this), there's a common parent type
that all returned types will extend or implement, so the caller doesn't
actually have to do instanceof - just use the methods on the parent type.

That's what polymorphism is intended for. If you're calling instanceof,
you're likely doing something a bit odd.

> For example, it would be great, if Java SE had an »input« method,
> which returned »java.lang.Integer« or »java.lang.String«
> depending on the text typed in the console.


1) If you think this would be great, write one. It's probably not more than a
dozen lines of code.

2) I think this would be less great than you think. It's rare that you want
to have random objects without a useful parent class/interface by which you
handle them all.

>public class Main
>{
> public static void main
> ( final java.lang.String[] args )
> {
> java.lang.System.out.println
> ( java.lang.System.in.input().getClass() ); }}
>
> Which would print »java.lang.Integer« (when one
> enters »123«) or »java.lang.String« (when one enters »abc«).


In practice, you ALWAYS want the String, then parse it to a more specific
type, with error handling and fallback in a type-safe way.

> The usual approach is to put objects of different classes
> into a heterogeneous container, then reading them in again,
> and - surprise! - get objects of different classes.


Huh? You still only get out what you put in. And you don't need a container,
just use a variable. "Object o" can be any reference type.

> Possibly, somewhere in the huge Java-SE API there is a little
> known field or method I could use.


For teaching purposes, why not write (or have students write) it? Something
like:

/*
* parse a String, returning a String, Boolean, or Integer, depending on
* the contents of the string. Returns null for null input.
*/
public static Object parseString(String input) {
if (input == null)
return null;

try {
// attempt to parse as int. if success, return it.
return new Integer(Integer.parseInt(input));
} catch (NumberFormatException nfe) { }
if ("true".equals(input))
return Boolean.TRUE;
else if ("false".equals(input))
return Boolean.FALSE;
else
return input;
}

Keep in mind that this is a crappy thing to do most of the time. You're going
to force users of this method to basically have the same if/else if/else logic
you have here, except with instanceof instead of testing directly.
--
Mark Rafn http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.dagon.net/>
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      12-22-2007
Stefan Ram wrote:
> For teaching purposes, I'd like to know a Java-SE method
> that returns an object whose class is only known at runtime
> and can be shown to have at least two possibly values by
> running a small program.
>
> It would be best if this would be a static method that can
> be called without any preparation.
> [...]


Use Collections.unmodifiableList() on a List reference that
is made to refer to various kinds of Lists:

List list = new ArrayList();
Class c1 = Collections.unmodifiableList(list).getClass();
list = new LinkedList();
Class c2 = Collections.unmodifiableList(list).getClass();
list = Arrays.asList(argsOfMain);
Class c3 = Collections.unmodifiableList(list).getClass();

Maybe not compelling enough, because even though the List-ness
of list doesn't determine the class of the unmodifiable wrapper,
the actual nature of the object it refers to does. Maybe a more
direct example would be to use the parse() method of a NumberFormat
and show that sometimes it returns a Long and sometimes a Double.

A slightly different wrinkle: Catch an IOException and show
that different kinds of run-time failures generate different
subclasses: FileNotFoundException, EOFException, ...

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
Arne Vajhøj
Guest
Posts: n/a
 
      12-22-2007
Stefan Ram wrote:
> For teaching purposes, I'd like to know a Java-SE method
> that returns an object whose class is only known at runtime
> and can be shown to have at least two possibly values by
> running a small program.
>
> It would be best if this would be a static method that can
> be called without any preparation.


A well known and not that difficult to setup example
would be DriverManager.getConnection.

Arne
 
Reply With Quote
 
Karl
Guest
Posts: n/a
 
      12-22-2007


"Stefan Ram" <(E-Mail Removed)-berlin.de> wrote in message
news(E-Mail Removed)-berlin.de...
> For teaching purposes, I'd like to know a Java-SE method
> that returns an object whose class is only known at runtime
> and can be shown to have at least two possibly values by
> running a small program.
>
> It would be best if this would be a static method that can
> be called without any preparation.
>
> For example, it would be great, if Java SE had an »input« method,
> which returned »java.lang.Integer« or »java.lang.String«
> depending on the text typed in the console.
>
> Then I could write:
>
> public class Main
> {
> public static void main
> ( final java.lang.String[] args )
> {
> java.lang.System.out.println
> ( java.lang.System.in.input().getClass() ); }}
>
> Which would print »java.lang.Integer« (when one
> enters »123«) or »java.lang.String« (when one enters »abc«).
>
> However, I am not aware of such a method.
>
> The usual approach is to put objects of different classes
> into a heterogeneous container, then reading them in again,
> and - surprise! - get objects of different classes.
>
> I wonder, if it can get any simpler, without a container,
> without preparation.
>
> A near miss is the field »System.in«, which indeed contains an
> object of a proper /subtype/ of the field's type. So it is
> somewhat polymorphic. You do not know the actual type until
> run-time. It is only boring insofar as it is always the same
> subtype.
>
> Possibly, somewhere in the huge Java-SE API there is a little
> known field or method I could use.


From your post, I am not sure if you are really more interested in
polymorphism or reflection. If it is really polymorphism you are interested
in, java.lang.Number is a perfectly good example. All of the Java primitive
numeric wrappers extend Number, and you can get the value in any primitive
form, plus as a String, just by calling the methods on the base class. You
don't need to have any idea what object you are using. Taking it even a bit
further, all Java objects extend object, which provides polymorphic methods
for synchronization, hash functions and comparison, and toString.

Your program/method could create Float, Integer, Short, etc., based on a
user input string, and return a Number.

If you want reflection with a polymorphic outcome, why not just use
java.lang.Class.forName and newInstance? The Object instance you will get
back will be as polymorphic as you want it to be. It will return type T of
the Class you are using to create the instance. This is the usual way to
create instances whose types are not known, or even conceived of, until
run-time.

Your program/method could create whatever type the user enters on the
command line (e.g., "java.lang.String") and return an Object. An exercise
for the student would be figuring out how to create new instances of classes
that do not have a zero-arg constructor.


 
Reply With Quote
 
Karl
Guest
Posts: n/a
 
      12-22-2007
Oops -- I got carried away -- java.lang.Object is not comparable. Sorry
about that.


 
Reply With Quote
 
Mark Space
Guest
Posts: n/a
 
      12-22-2007
Stefan Ram wrote:
> For teaching purposes, I'd like to know a Java-SE method
> that returns an object whose class is only known at runtime
> and can be shown to have at least two possibly values by
> running a small program.


Here's my entry. I make some Swing components, then print out their
actual type. Swing makes heavy use of polymorphism, and does so for
good reasons. It's overall an excellent case study for students.

First I make a simple JOptionDialog. Then I print out all of the types
that it contains. The method which returns the components says they
should be all of type Component, but actually their all different,
descendant types.

You'll need to fix up the line breaks a bit. Output follows.



package polymorphism;

import java.awt.Component;
import java.awt.Container;
import javax.swing.JOptionPane;

/** Check the insides of a JFileChooser.
* <p>
* This will demonstrate the use of polymorphism in Java.
*/
public class PolyCheck {

/** Called from the command line.
*
* @param args the command line arguments are igonred.
*/
public static void main(String[] args) {
// TODO code application logic here
final JOptionPane optionPane = new JOptionPane(
"The only way to close this dialog is by\n" +
"pressing one of the following buttons.\n" +
"Do you understand?",
JOptionPane.QUESTION_MESSAGE,
JOptionPane.YES_NO_OPTION);

// First polymorphism: optionPane is a JOptionPane but we can
// treat
// it like a Container.

printComponents(optionPane, 0);

}

public static void printComponents(Container cont, int offset) {

Component[] comps = cont.getComponents();

// comps should be all Components, but let's see what they
// really are.

for (Component c : comps) {
System.out.println( repeat( " ",offset*4
)+c.getClass().getName());
if( c instanceof Container ) {
printComponents( (Container)c, offset+1 );
}
}
}

public static String repeat( String s, int times ) {
StringBuffer sb = new StringBuffer();
for( int i = 0; i < times; i++ ) {
sb.append( s );
}
return sb.toString();
}
}

---------------------
Output:
javax.swing.JPanel
javax.swing.JPanel
javax.swing.JPanel
javax.swing.JPanel
javax.swing.JLabel
javax.swing.JLabel
javax.swing.JLabel
javax.swing.JLabel
javax.swing.JPanel
javax.swing.JButton
javax.swing.JButton
 
Reply With Quote
 
Patricia Shanahan
Guest
Posts: n/a
 
      12-22-2007
Stefan Ram wrote:
....
> A near miss is the field »System.in«, which indeed contains an
> object of a proper /subtype/ of the field's type. So it is
> somewhat polymorphic. You do not know the actual type until
> run-time. It is only boring insofar as it is always the same
> subtype.

....

Huh? Why do you say it is always the same subtype?

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class SystemDotInClasses {
public static void main(String[] args) throws IOException {
System.out.println("Initial class: "
+ System.in.getClass().getName());
String someData = "xyzzy";
InputStream someStream = new ByteArrayInputStream(
someData.getBytes());
System.setIn(someStream);
System.out.println("Second class: "
+ System.in.getClass().getName());
int firstByte = System.in.read();
if (firstByte == -1) {
System.out.println("Empty input");
} else {
System.out.println("First byte of input: "
+ (char) firstByte);
}
ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(outBytes);
out.writeDouble(Math.PI);
someStream = new DataInputStream(
new ByteArrayInputStream(outBytes.toByteArray()));
System.setIn(someStream);
System.out.println("Third class: "
+ System.in.getClass().getName());
double d = ((DataInputStream) System.in).readDouble();
System.out.println("Read from data stream " + d);
}
}

Patricia

 
Reply With Quote
 
Stefan Ram
Guest
Posts: n/a
 
      12-22-2007
http://www.velocityreviews.com/forums/(E-Mail Removed)-berlin.de (Stefan Ram) writes:
>For teaching purposes, I'd like to know a Java-SE method
>that returns an object whose class is only known at runtime


Thanks for the answers so far!

Why do I not write a custom method or class for this?

I have this idea that teaching should go from the simple
things to more advanced things. To me, /using/ objects of
JAVA-SE classes is more simple than /declaring/ custom classes
(eating is more simple than designing a dish and cooking it).

Therefore, when I introduce objects and their properties,
I have not yet introduced class or non-static method
declarations: Most statements still go into the body of
the static »main« method.

So, at this point, I would like to show how to /use/
polymorphic designs, but not yet how to create a new
design.

»DriverManager.getConnection()« might be of no use when used
in isolation and a full JDBC client might be too large at this
point.

To use the parse() method of a NumberFormat (Eric)

http://download.java.net/jdk7/docs/a....ParsePosition)

, is very close to what I was looking for.

I will also look into catching an IOException,
Calendar.getInstance(), java.lang.Class.forName and
newInstance and other suggestions.

One example I already use, but which looks somewhat contrived
and not like the solution of any real problem is:

( Math.random() > .5 ? System.out : "example" ).hashCode()

This is simple: No containers, no declarations, just
polymorphism. There is an expression for an object whose
type is only known at run time and a verb »hashCode«, which
indeed has two completely different implementations in
both cases. This is good so far.

The problem is: This example makes no real sense: One can not
imagine that one really needs this specific expression to
solve any problem. So I am looking for something as simple and
polymorphic as this but with more sense. Possibly I can use
the abovementioned »parse« verb for this.

 
Reply With Quote
 
Stefan Ram
Guest
Posts: n/a
 
      12-22-2007
Patricia Shanahan <(E-Mail Removed)> writes:
>>A near miss is the field »System.in«, which indeed contains an
>>object of a proper /subtype/ of the field's type. So it is
>>somewhat polymorphic. You do not know the actual type until
>>run-time. It is only boring insofar as it is always the same
>>subtype.

>Huh? Why do you say it is always the same subtype?


Said »always the same subtype«,
thought »always the same subtype at the start of a program«.

Sorry, I should also have written »at the start of a program«.

>System.setIn(someStream);


Yes, indeed. This is possible. Thank you.

Here one party (your code) sets the field and then /the same
party/ reads it in again. I believe it might be more
suggestive when polymorphism is used for communication between
/two/ parties. Therefore, I searched for a Java-SE factory
method, so that I can show, how Java SE conveys information to
an application by a polymorphic expression.

(I have not yet acknowledged Marks post in my previous post,
because I had not read it then. So I'd also like to thank him
for the Swing example.)

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Polymorphism in Java priya Java 6 06-18-2006 12:11 PM
Polymorphism in Java priya Java 0 06-15-2006 01:30 PM
Polymorphism in Java priya Java 0 06-13-2006 05:30 PM
Polymorphism in Java priya Java 0 06-11-2006 02:42 PM
Dynamic polymorphism vs. Static polymorphism Krivenok Dmitry C++ 13 06-01-2006 09:49 AM



Advertisments