Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is FilterOutputStream a concrete class?

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?

like image 648
Gonen I Avatar asked Sep 05 '25 17:09

Gonen I


2 Answers

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.

like image 100
biziclop Avatar answered Sep 07 '25 18:09

biziclop


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.

like image 38
Slimu Avatar answered Sep 07 '25 17:09

Slimu