[1872] in java-interest

home help back first fref pref prev next nref lref last post

re: extending String functionality

daemon@ATHENA.MIT.EDU (Glen C. Perkins)
Tue Sep 19 00:52:43 1995

Date: Mon, 18 Sep 1995 17:48:47 -0700
To: java-interest@java.sun.com
From: Glen.Perkins@MediaCity.com (Glen C. Perkins)

I must have been asleep, but I didn't realize until this thread started
that most of the fundamental classes (String, Integer, Float, etc.) are
"final" classes meaning they can't have subclasses.

This came as a shock because I thought the reason for having an "Integer"
class in addition to the plain "int" data type was to allow subclassing to
create special types of integers (something fancier that just "between MIN
and MAX). I was assuming we were able to create such things as "JIS1String"
as a Japanese subclass of String, or PrimeNumber as a subclass of Integer.
The constructors for these special data types (a special type of String or
a special type of Integer) could do very fancy validity checking. If you
tried to create a JIS1String using a kanji that was actually up in the JIS2
character set, it would throw an exception. Then, if you had an array of
Strings and pulled one out, you could ask the object for its type. If it
said it was a "JIS1String", you could confidently send it to a display
system that was limited to JIS1 characters and couldn't handle JIS2. If it
said it was a JIS2String, you could call a different method (probably
apologize profusely in Japanese for your inadequacy ;-)  ).

As a subclass of String, you'd have all the methods available to all
Strings, plus a few of your own. And you could put JIS1Strings together
with HangulStrings and ThaiStrings etc. all in the same array of type
String[]. This seems like such a natural benefit of Java's basic design
(Strings as first class objects composed of Unicode chars) that I've been
parading around telling everyone who would listen about this wonderful
feature of Java. Ooops. (Where's that face, I keep losing it...?)

The only thing I can figure is that by finalizing String, Integer, Float
and so on (so that they can't be subclassed to suit your needs EXACTLY) you
gain some benefit in some other way. Probably, as someone else was
surmising, either performance or security or both. Does anyone actually
know why this was done?

If those classes are all dead ends, sorry, "final", was the intention that
we create a new base class ("MyString" was mentioned, but I'll call it
"SuperString") that simply encapsulates a String attribute, then subclass
it to create JIS1String, ThaiString, etc?

Do we then create an array of SuperString instead of String if we want to
work with an array containing different types of strings?

(These aren't rhetorical questions, by the way. I'm assuming that there is
an excellent reason for making the fundamental classes final. I'll be using
plain old Strings a lot more often than special strings such as JIS1, so if
finalizing boosts our performance five-fold, it's a smart trade off. Now,
though, I'm trying to figure out how to specialize Strings and Integers the
"hard way". Is the following correct, or am I still out in left field
(...or both? ;-)   ))

Another poster was mentioning having to create wrappers for all of the
methods in String in order to include them in this homemade base I'm
calling "SuperString". If I were to do it, I'd just call the methods of the
String variable encapsulated within the subclass. For example, I create the
class "SuperString" and it has one variable in its definition:

class Superstring () {
String theActualString;
...}

and no methods. Then I create a subclass of SuperString called
"JIS1String". It adds a constructor that makes sure the argument passed to
it is one of the JIS1 characters (and maybe adds some other useful
methods).

When I need a JIS1String object, I create it:

JIS1String myKanjiString;

then I can use all of the String methods (such as charAt(int) ) by calling
them like this:

If (myKanjiString.theActualString.charAt(3) == "\u3456") { ... }

That way, I don't have to build wrappers for all of the String methods so
that my non-final SuperString class would be able to use them. I'd just
have to live with saying

myKanjiString.theActualString.charAt(3)

instead of:

myKanjiString.charAt(3)

Is this basically what it was intended that we do in order to create
subclasses of String or Integer or Float or whatever? What about
encapsulation? Should

String theActualString;

in the SuperString base class definition actually be made public:

public String theActualString;

Enquiring minds want to know!

Thanks,
__Glen__


-
Note to Sun employees: this is an EXTERNAL mailing list!
Info: send 'help' to java-interest-request@java.sun.com

home help back first fref pref prev next nref lref last post