Re: abstract static methods (again)
Andreas Leitgeb wrote:
[...]
I still see some merit in being able to enforce that any concrete
class implementing some thusly declared interface had to offer some
particular c'tor, as a means to help developers of such classes to
not forget about it.
That doesn't strike me as a great idea, because it constrains
the subclass' implementation rather than its interface. It may be
tempting to view a class' constructors as "sort of methods" and as
such part of the interface, but I don't think it holds up.
Here's my objection: Suppose there's an Entertainer interface
(or abstract class) and I'm writing concrete implementations of it.
I write Actor and Singer, but when I come to Comedian I realize
that every Comedian must have a Joke he can fall back on when the
act is dying: A Comedian without a shop-worn stale Joke is no
Comedian at all. So to ensure that all Comedians are viable, I
give the class a Joke member and initialize it in the constructor:
class Comedian implements Entertainer {
private final Joke jokeOfLastResort;
Comedian(Joke joke) {
if (joke == null)
throw new IllegalArgumentException("not funny");
jokeOfLastResort = joke;
}
...
}
But suppose that Entertainer (somehow) requires all implementing
classes to provide a no-arguments constructor -- maybe even a public
no-arguments constructor. How will a Comedian instantiated with that
constructor acquire his jokeOfLastResort? We can't let it be null (a
Comedian with no Joke would be a Politician), so we're forced to invent
some kind of default Joke the no-arguments constructor can use:
class Comedian implements Entertainer {
... as above ...
private static final Joke DEFAULT =
new Joke("Plato and a platypus walk into a bar...");
public Comedian() {
this(DEFAULT);
}
...
}
Okay, it might make sense for the class of Comedians to have a
default stale Joke (a faithful model of reality, perhaps), but note
that the need for something like DEFAULT was *forced* upon us by the
requirement for a no-arguments constructor. The author of Entertainer,
who knew nothing about the wants and needs of those who would come
later, decreed that every implementing class would have usable default
values for everything that might ordinarily be passed as arguments to a
constructor. Is that much coercive power a good thing to put in the
hands of the Entertainer author?
I guess one could always evade the requirement:
class Comedian implements Entertainer {
...
public Comedian() {
throw new UnsupportedOperationException(
"Please don't use this constructor");
}
...
}
.... but one would then have to wonder about the utility of Expression's
requirement that the constructor exist.
--
Eric.Sosman@sun.com