Reputation: 6127
Java's FilterOutputStream is part of the Stream decorator pattern in Java. It is the intermediate, base decorator class.
From the documentation:
The class FilterOutputStream itself simply overrides all methods of OutputStream with versions that pass all requests to the underlying output stream. Subclasses of FilterOutputStream may further override some of these methods as well as provide additional methods and fields.
My students asked me why this class is concrete, and I am having a hard time coming up with a good reason. Is this just an oversight?
Any ideas?
Upvotes: 4
Views: 290
Reputation: 2371
I think that FilterOutputStream
acts as a skeletal implementation for the abstract OutputStream
class, offering a minimum implementation. After that, each class which extends it will override only methods which are different from that original implementation. I think a similar class would be something like AbstractList, with the mention that it's abstract since some of the methods you are required to implement. The FilterOutputStream doesn't need to be declared abstract since it implements the only abstract method from OutputStream
- write()
Since it's not abstract you can do something like this:
FilterOutputStream stream = new FilterOutputStream(System.out);
stream.write(65);
stream.flush();
stream.close();
This will print the character A on the System.out stream, but it can be used with other output streams.
Upvotes: 1
Reputation: 1254
Consider asking the reverse: "Why should it be abstract, when all methods are implemented, and there are no abstract methods?"
All methods are implemented, none are abstract, so why should it be an abstract class, when it is completely implemented?
Why should a user of the API be forced to subclass a class, placing an additional unnecessary burden on the user? What if the user is working in a JVM with almost no memory, and every byte (i.e. class definition) counts? There can be concrete physical problems by making it abstract, whilst only stylistic problems by making it not abstract.
Your API should be as weak as possible for your users (i.e. place as little restrictions on its use as possible). It is not your task to force users to write a certain way, because it might hamper them in a case which you haven't thought of.
Upvotes: 0
Reputation: 49794
Technically it doesn't have to be abstract
, but if you look at it from a strict OO viewpoint, it is an oversight, yes.
There is no sense instantiating a plain FilterOutputStream
, which is the textbook definition of an abstract class. In fact, the Javadoc spells it out even clearer, defining the purpose of this class as:
This class is the superclass of all classes that filter output streams. These streams sit on top of an already existing output stream (the underlying output stream) which it uses as its basic sink of data, but possibly transforming the data along the way or providing additional functionality.
Since its sole purpose is to serve as a superclass for other implementations, marking it abstract
would be more than justified.
The moral of the story is that just because it's a java.*
class, it doesn't mean it's good OO. There are plenty of examples of compromise, and sometimes outright poor design there, some of them far worse.
Upvotes: 3