3

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?

Lucky
  • 16,787
  • 19
  • 117
  • 151
Gonen I
  • 5,576
  • 1
  • 29
  • 60

3 Answers3

2

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.

biziclop
  • 48,926
  • 12
  • 77
  • 104
  • If its current (sole) purpose is being a superclass, as an API designer, would you want to place the restriction on your users by making it the class sole purpose to do so? (kinda weirdly said, but: even though, as-is, it's only doing one thing, should that thing be the only thing it's allowed to be used for, even though it can do more?) – Koos Gadellaa Sep 07 '16 at 11:03
  • 1
    @KoosGadellaa If we're strict about OO, then yes. Bearing in mind the context of the original question, if it's a class about OO, the answer is definitely: it should be abstract. If it's a class about API design, you could have a nice argument about it, but from a pure OO perspective (which only exists in a classroom) this is an abstract class. – biziclop Sep 07 '16 at 11:57
  • Agreed. So that's probably the answer @Lucky is going for: From an OO perspective, it should be abstract. From an API perspective, it shouldn't be because it adds an additional burden on the user. And since it's an API, it's not abstract. – Koos Gadellaa Sep 07 '16 at 12:09
1

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.

Slimu
  • 2,301
  • 1
  • 22
  • 28
  • It's true that it doesn't need to be declared abstract. But making a class concrete suggests to a user that he might have use instantiating it. The question is if there is any need to. – Gonen I Sep 07 '16 at 11:10
  • 1
    In a normal use case, I don't think there is a need to create directly an instance of this class since you would use a more specialized subclass of it. – Slimu Sep 07 '16 at 11:31
0

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.

Koos Gadellaa
  • 1,220
  • 7
  • 17
  • 2
    That's asking the wrong question IMO. Marking a class abstract has nothing to do with whether it has abstract methods or not. (Except in the obvious direction: if you've got abstract methods, the class **must** be abstract.) A class should be abstract when you're not supposed to instantiate it, regardless of whether it has abstract methods or not. – biziclop Sep 07 '16 at 10:38
  • 1
    Quite the opposite: it adds clarification about the purpose of the base class, i.e. that it's purely a base class. If you give it a private constructor, how are you going to extend it? :) Arguably a better solution in cases like these is to use composition instead of inheritance, but failing that, marking a base class as `abstract` is correct from an OO point of view.) – biziclop Sep 07 '16 at 10:55