I am reminded that it is good to remember that we can use templates to take advantage of "isa:" In C# and Java specifically, since all classes are reference types (object pointers), the universal object-placeholder is Object. From a template's point of view, Everything 'isan' Object.

What does having a universal Object for absolutely all classes, mean? -Well, much like using "void *" in C/C++, Java and C#'s Object offers us all of that polymorphic goodness, as well as some sophisticated base operations.

To demonstrate the former, given the following template + interface combination:

What is interesting to keep in-mind here is that, because MyNewClass is-an Object, that we can xForm one type, to another. -Even if MyNewClass is only used by a single, solitary function - as long as the compiler can find it - then we can return it.

Too Much Knowledge?

For the tenured C++ developer, both C# and Java have their thrills - as well as their chills.

For many, one of the chills can occur when your templates are prematurely inspected by that Java or C# Compiler. While absolutely similar to C++ in many ways, in other ways the C# and Java compilers arguably check templates far too early to ensure that a class member might (or might not) be there!

Templates (aka "parameterized types")

Take for example the need to return a generic object - classically referenced as a generic typeT - via a template. While templates are common to C++, Java, and C# (order of plagiarism), there are some very subtle differences in when those me-too compilers allow templates to be applied.

In C++, for example, template implementations are comparatively overlooked until they are required. Ignoring templates until they are used means that while the intention behind:

class MyClass<T> {...}

-is clear in all 3 languages, the compile-time realties can be very different, indeed.

How different? Well, the intent to declare a T as our yet-to-be defined class is obvious. But what if we want T to also be used in a certain way? What if we need to be sure that T has a T.read(RandomAccessFile), for example?

Interface Compliance

Upon first blush, one might quite naturally assume that a C# or Java interface can be used. Something like (in Java):

class MyClass<T implements MyCommonStufToDo> {...}

Yet, try as we might, at the time of this writing there seems to be no way in either C# or Java to do what - because of a far more relaxed template-checking policy - we can easily do in C++. Namely, insure that our T has implemented a few member functions.

After a few head-scratching moments however, there IS indeed another way to proffer BOTH a reusable template implementation, as well as to assure required operational support, too: Just provide your template with an Object-Factory as a template Interface.

Templates & the Factory Interface

While the C++ way of assuming class-members for a parametrized type is impossible in C# and Java, one great work-around is to leverage a touted feature: The Java & C# need to avoid multiple-inheritance, by using Interfaces. Rather than having MyCommonStufToDo a descendant of T therefore, we simply provide a factory for T where needed:

That T result = factory.read(reader); is the important bit. -If you are not familiar with the rest, then feel free to ignore the use of my com.soft9000.dbo file-indexing framework (IndexLogical, etc..)

That factory.read(reader) demonstration nicely completes a succinct pattern for C# and Java. I have found it to be a viable stratagem. One that allows us to have our re-use (templates), strong-type checking (T), as well as a ubiquitous signature guarantee (interface<T>) for a yet-undefined template-type, as well.

Enjoy!

-Rn

p.s. If I have given the reader the impression that C++ template support is superior to those of Java or C#, make no mistake: When it comes time to link-together objects - certainly those that have been compiled between divergent Standard C++ Template libraries - then the tao of the template is an entirely different story! If we do not have the source code, then give us C# or Java over template-laden C++, A-N-Y-T-I-M-E! :)

(Come to think of it, knowing several technologies is far, far, better than knowing just a few. -Knowing the alternatives allows one to avoid the nearsighted language-camps & technology "religious wars." --We are instead free to pick the right tool, for the right job, for the right-reasons! (requirements, anyone?))

There is something truly wonderful about keeping those old computers doing useful things. -So as everyone from Apple to Microsoft encourages us to chum our old hardware into the ocean by dropping support, I find more and more reasons to convert them from Windows, OS 9, or OS X, to Linux.

Indeed, as feature-bloat & patches make proprietary operating systems slower and slower each day, many have discovered that even 12-year-old hardware can do some pretty mainframe-worthy operations. All due to the lightweight machine requirement of Linux!

Dusting off a few G3s today, here is the process:

(1) Create a bootable CD from the ISO. Because I prefer the long-time support versions (LTS), we used Lucid Lynx (Version 10.04.) A CD-R worked fine.

(2) Start the computer, then insert the CD into that iMac (or any Apple PowerPC.)

(3) Re-start the computer, afterward holding down the 'c' key until the CD boots.

(4) Use the 'live' video option, as mentioned at the boot prompt. (i.e boot: video=ofonly)

(5) When the install complains, use the default low-res setting for a "this boot only" option.

(6) Once the graphical Ubuntu screen shows, wait a few minutes to cancel the package management prompting. -While this step is optional, it makes things a whole lot easier to understand.

(7) Click on the install icon, and install as prompted / desired.

(*) Note that once Ubuntu is installed, that the disk will automatically eject. If you abort the installation, remember that holding the mouse button down after the "wall-(e) sound" will eject the CD during the early stages of a re-boot. You can also try this.

(*) Once the Ubuntu GUI is running (visible or not), note also that pressing ctrl-option-F1 will give us a command prompt. When the live boot is in pester, starting a terminal session using this combination might take a couple of tries... but it works just fine.

(8) Finally, to disable that incessant request to change your password each and every time you run a command-prompt (is your date / time battery not holding a charge?), then change the '0' to being completely empty in the last-date-change field. -That field will be the 3rd field on the line containing your login name in the /etc/shadow file. More information can be had via the `man shadow` page. If you are new to Linux, then the `man passwd` page is also worth a read.

If and when you get tired of manually asserting the default video mode, rumor has it that the "video-ofonly" is in yaboot.conf. -Someone else mentioned that you could also try adding nomodeset to the kernel command line. (Since I use the G3s as non-gui servers, I have not been too concerned about X11. While you can use apt-get to remove the GUI entirely, you can also edit the /etc/rc.local script to fix-in a shell. We can then use startx whenever we want to GUI.)

If you do not want a GUI, note that there are ever more creative ways to stop the GNOME Display Manager (gdm) from starting. Take a Google to find out how...

Enjoy,

-Rn

(p.s. If you like those magic Apple key-combinations, then here is a nice list of them.)