Using "abstract" on a class with no abstract method

S

Stefan Ram

I have a class that is intended for subclassing,
not for instantiation.

So I thought, I could tag it with »abstract«,
even though it does not have any abstract method.

Is this a good idea? Can human readers understand
this application of »abstract«?

Here is the concrete example:

abstract class MainCommand
extends de.dclj.ram.DefaultDirectedMessage
{ public MainCommand( final int direction ){ super( direction ); }
@java.lang.Override public java.lang.String description(){ return "MainCommand"; }}

class QuitMainCommand extends MainCommand
{ public QuitMainCommand( final int direction ){ super( direction ); }}

»abstract« is foremost a kind of comment, intended
for human readers of the source code, here.
 
M

Mike Schilling

Stefan said:
I have a class that is intended for subclassing,
not for instantiation.

So I thought, I could tag it with »abstract«,
even though it does not have any abstract method.

Is this a good idea? Can human readers understand
this application of »abstract«?

Yes and yes, though it might be clearer still if you declare the
constructor as "protected", to emphasize that it's intended to be
called only from subclasses
 
A

Arved Sandstrom

Stefan said:
I have a class that is intended for subclassing,
not for instantiation.

So I thought, I could tag it with »abstract«,
even though it does not have any abstract method.

Is this a good idea? Can human readers understand
this application of »abstract«?
[ SNIP ]

It's a legitimate use, and common enough.

AHS
 
E

Eric Sosman

Stefan said:
I have a class that is intended for subclassing,
not for instantiation.

So I thought, I could tag it with »abstract«,
even though it does not have any abstract method.

Is this a good idea? Can human readers understand
this application of »abstract«?

Here is the concrete example:

abstract class MainCommand
extends de.dclj.ram.DefaultDirectedMessage
{ public MainCommand( final int direction ){ super( direction ); }
@java.lang.Override public java.lang.String description(){ return "MainCommand"; }}

class QuitMainCommand extends MainCommand
{ public QuitMainCommand( final int direction ){ super( direction ); }}

»abstract« is foremost a kind of comment, intended
for human readers of the source code, here.

You can do it, but why? If the MainCommand class has no
abstract methods but only "concrete" methods, it appears
that a MainCommand object has all the code required to
stand on its own, to be a full-fledged object regardless
of subclasses. If it can operate on its own, fulfilling its
role in the program/framework/whatever, why make it abstract?

If MainCommand can't really stand on its own because it
has a method that is fully implemented but "deficient" in
some way (the idea being that subclasses provide the missing
bits and then call super.method() from overriding methods),
maybe the situation would be made clearer with a few name
changes, and possibly marking the deficient method as protected.
That is, instead of

/* abstract */ class Super {
/** You probably want to override me */
void method() {
// incomplete implementation
}
}

class Sub extends Super {
@Override // Yeah, I guess I probably do
void method() {
// pre-stuff
super.method();
// post-stuff
}
}

you'd have

abstract class Super {
/** Possibly useful in implementing method() */
/* protected */ void methodGuts() {
// incomplete implementation
}
/** You <b>must</b> override me */
abstract void method();
}

class Sub extends Super {
@Override // Got no choice, do I?
void method() {
// pre-stuff
methodGuts(); // Wow, that's convenient!
// post-stuff
}
}

Opinions may (i.e., "will") vary, but for me the latter
more clearly expresses the "Should be overridden" message.

Hmmm: Here's a thought experiment. Suppose we go with
the "abstracted concrete class" and demand that it be
subclassed. Would this subclass be acceptable?

class ThoughtExperiment extends Super {
@Override
void method() {
super.method(); // That's all, folks!
}
}

If it's acceptable, why not just use Super directly? If it's
not acceptable, why not -- and can you find a way to express
the "why not" in Java?
 
L

Lew

Mike said:
Yes and yes, though it might be clearer still if you declare the
constructor as "protected", to emphasize that it's intended to be
called only from subclasses

Redundant.
 
L

Lew

Stefan said:
I have a class that is intended for subclassing,
not for instantiation.

So I thought, I could tag it with »abstract«,
even though it does not have any abstract method.

Is this a good idea? Can human readers understand
this application of »abstract«?

Human readers could understand it a whole heck of a lot better if you used a
reasonable and conventional indentation style instead of the crap you show here.
 
D

Daniel Pitts

Lew said:
Redundant.
Redundancy isn't useless. Especially when it reinforces a concept or
intent. I'd argue the declaring a public or private constructor in an
abstract class is contradictory and should be a avoided.
 
D

Daniel Pitts

Stefan said:
I have a class that is intended for subclassing,
not for instantiation.

So I thought, I could tag it with »abstract«,
even though it does not have any abstract method.

Is this a good idea? Can human readers understand
this application of »abstract«?

Here is the concrete example:

abstract class MainCommand
extends de.dclj.ram.DefaultDirectedMessage
{ public MainCommand( final int direction ){ super( direction ); }
@java.lang.Override public java.lang.String description(){ return "MainCommand"; }}

class QuitMainCommand extends MainCommand
{ public QuitMainCommand( final int direction ){ super( direction ); }}

»abstract« is foremost a kind of comment, intended
for human readers of the source code, here.
Yes, but often times it is a sign of a design flaw. What does this
hierarchy give you that doesn't involve implementing methods
differently? You shouldn't have to use instanceof or .getClass() in
order to handle the subclasses in a useful way.
 
A

Arved Sandstrom

Daniel said:
Yes, but often times it is a sign of a design flaw. What does this
hierarchy give you that doesn't involve implementing methods
differently? You shouldn't have to use instanceof or .getClass() in
order to handle the subclasses in a useful way.
One typical case where I'd expect to see an abstract base class with no
abstract methods is if we have a family of similar classes where a
subset of methods are identical in implementation. But the base class
itself is uninteresting, so is not to be instantiated. Each subclass
adds further method implementations that result in sensible class
definitions.

In JPA this case can happen a lot, where all (or most entities) have
some common fields. Those common fields, hence their getters and
setters, can be placed in a single @MappedSuperclass, which is declared
abstract. Other common methods that can go here are implementations of
entity lifecycle callbacks.

AHS
 
M

Mike Schilling

Arved said:
One typical case where I'd expect to see an abstract base class with
no abstract methods is if we have a family of similar classes where
a
subset of methods are identical in implementation. But the base
class
itself is uninteresting, so is not to be instantiated. Each subclass
adds further method implementations that result in sensible class
definitions.

In JPA this case can happen a lot, where all (or most entities) have
some common fields. Those common fields, hence their getters and
setters, can be placed in a single @MappedSuperclass, which is
declared abstract. Other common methods that can go here are
implementations of entity lifecycle callbacks.

Similarly junit.framework.TestCase. It's abstract because it would be
a silly thing to instantiate (it would be a test that doesn't test
anything), but it has no abstract methods. If course, it's a special
case of sorts; each subclasses adds test methods using a naming
convention, and these methods are found by reflection.
 
M

Mike Schilling

Mike said:
Similarly junit.framework.TestCase. It's abstract because it would
be
a silly thing to instantiate (it would be a test that doesn't test
anything), but it has no abstract methods. If course, it's a
special
case of sorts; each subclasses adds test methods using a naming
convention, and these methods are found by reflection.

HttpServlet is a better example. It's abstract because a servlet with
no behavior is a useless thing, but it has a variety of methods that
can be overridden, none of them mandatory.
 
D

Daniel Pitts

Mike said:
Similarly junit.framework.TestCase. It's abstract because it would be
a silly thing to instantiate (it would be a test that doesn't test
anything), but it has no abstract methods. If course, it's a special
case of sorts; each subclasses adds test methods using a naming
convention, and these methods are found by reflection.

And both of those cases use reflection (or at least structure analysis).
That isn't in itself a bad thing, but isn't *that* common of a pattern.

If you really have similar base class, but individual methods might be
implemented differently, a Strategy pattern may be more appropriate,
over inheritance. That gives the additional ability of mix-and-match
for each "method" to be called, without having a combinatorially
explosive hierarchy.
 
D

Daniel Pitts

Mike said:
HttpServlet is a better example. It's abstract because a servlet with
no behavior is a useless thing, but it has a variety of methods that
can be overridden, none of them mandatory.
Perhaps, but the intent of HttpServlet is to have at least *one* method
overridden. Stefan's example did not. My question was more about his
specific case, not any other case.
 
S

Stefan Ram

Daniel Pitts said:
Yes, but often times it is a sign of a design flaw. What does this
hierarchy give you that doesn't involve implementing methods
differently? You shouldn't have to use instanceof or .getClass() in
order to handle the subclasses in a useful way.

You can read my mind!

Indeed, I might use »instanceof« with these classes.

Think of a graph of interconnected components
(so that a component might have »neighbor components«),
including - for example's sake - a clock component.

The clock component then might contain code like:

public void process( final Command command )
{
if( command instanceof clockCommand )
{
/* This command is intended for me! Let me process it: */

if( command instanceof quitClockCommand )
{ /* Some party wants me to quit */ }

else if( command instanceof adjustClockCommand )
{ /* I should adjust myself now */ }

else { /* There are only these two clock commands,
so this is unexpected. */ }

else
{ /* This command is just passing-through, I will broadcast
it to my neighbors, maybe it is intended for one of them. */
broadcastToNeighbors( command );
/* Yes: if they do not know the command, and broadcast it,
too, this will give an endless loop of command reposts.
The real code will address this, the code posted here into
Usenet is simplified. */ }}

I have a guilty conscience for the use of »instanceof«.
But how can this be implemented in a better way in this case?
 
S

Stefan Ram

Eric Sosman said:
and can you find a way to express the "why not" in Java?

I have tried to explain, what I intend to do with this
hierarchy in another posting that I posted here several
minutes ago under the same subject.
 
A

Arved Sandstrom

Stefan said:
You can read my mind!

Indeed, I might use »instanceof« with these classes.

Think of a graph of interconnected components
(so that a component might have »neighbor components«),
including - for example's sake - a clock component.

The clock component then might contain code like:

public void process( final Command command )
{
if( command instanceof clockCommand )
{
/* This command is intended for me! Let me process it: */

if( command instanceof quitClockCommand )
{ /* Some party wants me to quit */ }

else if( command instanceof adjustClockCommand )
{ /* I should adjust myself now */ }

else { /* There are only these two clock commands,
so this is unexpected. */ }

else
{ /* This command is just passing-through, I will broadcast
it to my neighbors, maybe it is intended for one of them. */
broadcastToNeighbors( command );
/* Yes: if they do not know the command, and broadcast it,
too, this will give an endless loop of command reposts.
The real code will address this, the code posted here into
Usenet is simplified. */ }}

I have a guilty conscience for the use of »instanceof«.
But how can this be implemented in a better way in this case?

Maybe I'm missing something here, but however you exactly set it up,
each command class should have a "process" or "execute" or "do" method
implementation, and you never write a

public void process( final Command command )

method in the first place, you call command.process() instead. After
all, your code snippet already demonstrates that you have a constructed
subclass instance available, therefore no "instanceof" stuff is needed.

I don't understand enough about what you're trying to do to address the
"passing through" and "neighbours" idea properly. However, to invert the
logic a bit, you've clearly got the information to decide _whether_ to
call command.process()...otherwise (see above) you never could have
constructed a Command subclass to pass to your "process" method in the
first place. So, wherever _that_ logic is, where you construct a Command
subclass, is perhaps where the logic should be to hand off to another
"neighbour" ("broadcast" as you put it).

AHS
 
S

Stefan Ram

Arved Sandstrom said:
I don't understand enough about what you're trying to do to address the
"passing through" and "neighbours" idea properly. However, to invert the
logic a bit, you've clearly got the information to decide _whether_ to
call command.process()...otherwise (see above) you never could have
constructed a Command subclass to pass to your "process" method in the
first place. So, wherever _that_ logic is, where you construct a Command
subclass, is perhaps where the logic should be to hand off to another
"neighbour" ("broadcast" as you put it).

The question is not whether avoidance of »instanceof« is
possible technically, but whether the resulting code will
be more readable and maintainable than the code using
»instanceof«.

Here is an SSCCE using »instanceof«.

Maybe someone wants to rewrite it so as to remove »instanceof«?
(In this case, keep in mind, that the type of neighbor
objects (here: »other«) changes at run-time and is not
known at compile time, because components are intended
to be added as run-time plug-ins. At coding time, we only
know that »other« is a »Processor« and thus will accept
a »Command«.)

abstract class Command { public boolean seen = false; }
interface Processor { public void process( final Command command ); }

/*** The clock component ***/

abstract class ClockCommand extends Command {}
class QuitClockCommand extends ClockCommand {}
class AdjustClockCommand extends ClockCommand {}
class Clock implements Processor
{ public Processor other;
public void process( final Command command )
{ if( command instanceof ClockCommand )
{ if( command instanceof QuitClockCommand )
java.lang.System.out.println( "quit clock" );
if( command instanceof AdjustClockCommand )
java.lang.System.out.println( "adjust clock" ); }
else
{ if( !command.seen && other != null )
{ command.seen = true; other.process( command ); }}}}

/*** The counter component ***/

abstract class CounterCommand extends Command {}
class QuitCounterCommand extends CounterCommand {}
class IncrementCounterCommand extends CounterCommand {}
class Counter implements Processor
{ public Processor other;
public void process( final Command command )
{ if( command instanceof CounterCommand )
{ if( command instanceof QuitCounterCommand )
java.lang.System.out.println( "quit counter" );
if( command instanceof IncrementCounterCommand )
java.lang.System.out.println( "increment counter" ); }
else
{ if( !command.seen && other != null )
{ command.seen = true; other.process( command ); }}}}

/*** The controller ***/

public class Main
{ public static void main( final java.lang.String[] args )
{
final Clock clock = new Clock();

{ /* Build a graph of connected components: */
clock.other = new Counter(); }

{ /* Send commands to a component: */
clock.process( new AdjustClockCommand() );
/* You can send a counter command to a clock, too: */
clock.process( new IncrementCounterCommand() ); }}}

/* This will print:

adjust clock
increment counter

*/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,708
Latest member
SherleneF1

Latest Threads

Top