[37] in java-interest
Re: abstract/native/overriding confusion
daemon@ATHENA.MIT.EDU (Chuck McManis)
Tue May 2 13:39:23 1995
Date: Tue, 2 May 1995 10:08:56 -0700
From: cmcmanis@scndprsn.Eng.Sun.COM (Chuck McManis)
To: java-interest@java.Eng.Sun.COM, Steve_Kilbane@cegelecproj.co.uk
>I've just started reading about Java, and I'm a little baffled. Since
>I'm new to both Java and OO programming, it seemed a good idea to
>start at the bottom, and work up. But what I found in classsrc/java/io
>has me confused.
This one bit me too, like most things in life its obvious when you look
back on it. To wit ...
When you create a "new" FilterOutputStream you pass it an object which
is an instance of a subclass of OutputStream. Now it has to be a subclass
because you can't just 'new' OutputStream as it has abstract (aka virtual)
methods that can't be instantiated. So let's say you created a new
FileOutputStream using :
FileOutputStream f = new FileOutputStream("/tmp/foo");
This class has a concrete version of 'write()'. Now you want to
create a FilterOutputStream into this file, you would
create that with:
FilterOutputStream fi = new FilterOutputStream(f);
This "works" because FileOutputStream is a subclass of OutputStream.
>... as far as I can see, means that FilterOutputStream.write()
>overrides OutputStream.write(), but I don't see what it actually
>calls. I expected to see:
> public native void write(int b);
>in FilterOutputStream. So what *does* implement the writing?
So now we can answer this question. In our new FilterOutputStream
'out' is _actually_ a FileOutputStream (in our example) and it has
an implementation of 'write' so when we invoke out.write(b) it writes
it to the file "/tmp/foo".
The short answer to your question is: The object 'out' implements
the write, we know it has a write() method because it is a subclass
of OutputStream and all subclasses of OutputStream have to define
a write method.
>I'm also confused about the semantics of "out.write(b)" -- which
>is obviously allowed -- compared with "super.write(b)" -- which
>shouldn't be allowed, according to the Language Spec, because
>it's a direct invocation of an abstract method.
Presumably you can now see the answer to this as well, the out.write()
invokes the write method for the class that 'out' _really_ is, not
OutputStream.write() which is abstract. As you point out super.write()
is in fact an abstract function and it would blow up if you called it.
That is also not what FilterOuputStream does, FilterOutputStream
creates a FilteredOutputStream out of a pre-existing output stream
type object and basically it interposes between the "standard"
OutputStream interface and the interface exported by the subclass you
passed it (in my example FileOutputStream.) This lets you add new
behaviours (in this case filtering) to an existing group of object
classes (in this case output streams). And since FilterOutputStream
is a subclass of OutputStream it is itself an output stream. Thus
any number of behaviours could be layered up on OutputStreams in this
way.
Hopefully that clears up your confusion,
--Chuck
-
Note to Sun employees: this is an EXTERNAL mailing list!
Info: send 'help' to java-interest-request@java.sun.com