Ensuring a method is overridden

M

Mike Amling

A certain class is used 80% of the time as is, and is extended 20% of
the time. I want to ensure that each subclass overrides a certain
method. The only way I can think of to do this is to put code in the
base class's constructors, and when the class being constructed is not
the base class, check that getDeclaredMethod does not throw a
NoSuchMethodException.
Does anyone know of a more efficient way? At compile time, maybe?

--Mike Amling
 
M

Morris Keesan

A certain class is used 80% of the time as is, and is extended 20% of
the time. I want to ensure that each subclass overrides a certain
method. The only way I can think of to do this is to put code in the
base class's constructors, and when the class being constructed is not
the base class, check that getDeclaredMethod does not throw a
NoSuchMethodException.
Does anyone know of a more efficient way? At compile time, maybe?

Why not just declare the method abstract in the base class?
Or am I misunderstanding something?
 
M

markspace

Mike said:
A certain class is used 80% of the time as is, and is extended 20% of
the time. I want to ensure that each subclass overrides a certain
method. The only way I can think of to do this is to put code in the
base class's constructors, and when the class being constructed is not
the base class, check that getDeclaredMethod does not throw a
NoSuchMethodException.
Does anyone know of a more efficient way? At compile time, maybe?

--Mike Amling


I agree that "abstract" is the way to go here. Make a base class with
that method abstract. Then make a new derived class that is final and
that is intended to be used 80% of the time, like the main class is now.

For the other 20% of the time, since the new class is final, programmers
will be forced to use the base class, which has one method abstract that
must be overridden.
 
R

Roedy Green

A certain class is used 80% of the time as is, and is extended 20% of
the time. I want to ensure that each subclass overrides a certain
method. The only way I can think of to do this is to put code in the
base class's constructors, and when the class being constructed is not
the base class, check that getDeclaredMethod does not throw a
NoSuchMethodException.
Does anyone know of a more efficient way? At compile time, maybe?

The other way out of this is to put an assert in the method that must
be overridden.

It could use this.class to figure out if it is working with a base
class or an extension. If they have overridden, the assertion won't be
there.

To get fancy you want to make it ok if they call super. You could look
at the stack. See http://mindprod.com/jgloss/trace.html

Others might have better ways of doing this with a run time check.

These is a similar problem that I suggested fixing in Bali. See
http://mindprod.com/jgloss/bali.html

If you write a method to override, but get the signature or spelling a
tad off, it WON'T override the base method, and the compiler won't
tell you. I wanted to use an explicit override keyword to make the
compiler ensure the definition indeed overrode something in the base
class. There is now an annotation for that.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"I mean, source code in files; how quaint, how seventies!"
~ Kent Beck (born: 1961 age: 48), evangelist for extreme programming.
 
L

Lew

Roedy said:
The other way out of this is to put an assert in the method that must
be overridden.

It could use this.class to figure out if it is working with a base
class or an extension. If they have overridden, the assertion won't be
there.

To get fancy you want to make it ok if they call super. You could look
at the stack. See http://mindprod.com/jgloss/trace.html

Others might have better ways of doing this with a run time check.

Since the 'abstract' keyword works, and reflection is both messy and slow,
eschew reflection.

Any time you code an instance to figure out what class it is in order to
decide which behavior to use, you've messed up. (To nitpickers: that's the
first order of approximation.)

(and the second)

(...)

You don't need a run-time check.
 
M

Mike Amling

Mike said:
A certain class is used 80% of the time as is, and is extended 20% of
the time. I want to ensure that each subclass overrides a certain
method. The only way I can think of to do this is to put code in the
base class's constructors, and when the class being constructed is not
the base class, check that getDeclaredMethod does not throw a
NoSuchMethodException.
Does anyone know of a more efficient way? At compile time, maybe?

Thank you to all who responded. I presume you recommend some kind of
proxy to ensure toString, equals, hashCode, etc. are overridden:

abstract class Basso {
protected abstract String abString();

public final String toString() {
return abString();
}
}

final class Extenso extends Basso {
public String abString() {
return "whatever";
}
}

--Mike Amling
 
M

markspace

Mike said:
Thank you to all who responded. I presume you recommend some kind of
proxy to ensure toString, equals, hashCode, etc. are overridden:


That works, and I think I've seen it done. However, consider a code
review instead. ;)
 
L

Lew

Mike said:
I presume you recommend some kind of
proxy to ensure toString, equals, hashCode, etc. are overridden:

abstract class Basso {
   protected abstract String abString();

   public final String toString() {
     return abString();
   }

}

final class Extenso extends Basso {
   public String abString() {
     return "whatever";
   }

}

That's sort of a strange suite of methods to require overriding. It's
already best practice to override toString, hashCode and equals,
though not "etc.". (What other methods of Object do you contemplate
overriding? Not much else makes sense to override.)

The pattern you show is a common one - define an abstract base class
with a public method that invokes abstract helper methods so that
subclasses can provide the varying parts. Often the abstract methods
are protected rather than public, since it's the wrapping method
(toString in your example) that you want client code to use, not the
helper method (abString).

Another approach is to define the desired methods completely in the
parent abstract class, not as abstract methods but with reasonable
behaviors so the child class doesn't really have to override but may.
That's the approach Object itself takes with these methods.

Another approach is to declare toString and the others abstract in
your base class.

<sscce>
package eegee;
abstract class AbstractOver
{
@Override abstract public String toString();
}
public class ForceOver extends AbstractOver
{
@Override public String toString()
{
return getClass().getName();
}
}
</sscce>
 
D

Daniel Pitts

Lew said:
That's sort of a strange suite of methods to require overriding. It's
already best practice to override toString, hashCode and equals,
though not "etc.". (What other methods of Object do you contemplate
overriding? Not much else makes sense to override.)

The pattern you show is a common one - define an abstract base class
with a public method that invokes abstract helper methods so that
subclasses can provide the varying parts. Often the abstract methods
are protected rather than public, since it's the wrapping method
(toString in your example) that you want client code to use, not the
helper method (abString).
Yet another approach is to move those methods out of the class
altogether, and use the Strategy pattern. This is my favored approach
if there are a lot (read "more than one") of the "methods" that would
need to be customizable, but mixing and matching the behaviors would
make sense.

This is kind of the upside down version of "Prefer Composition over
Inheritance". You're still preferring Composition over Inheritance, but
the main entity doing the preferring is what would have been the Base
Class (rather than the Derived Class)
 
R

Robert Klemme

Since the 'abstract' keyword works, and reflection is both messy and
slow, eschew reflection.

Also, asserts are (and should be) OFF most of the time.
Any time you code an instance to figure out what class it is in order to
decide which behavior to use, you've messed up. (To nitpickers: that's
the first order of approximation.)

(and the second)

(...)

You don't need a run-time check.

Right.

robert
 
M

markspace

Daniel said:
Yet another approach is to move those methods out of the class
altogether, and use the Strategy pattern. This is my favored approach
if there are a lot (read "more than one") of the "methods" that would
need to be customizable, but mixing and matching the behaviors would
make sense.


That's interesting. The classic solution to "mixing and matching
behavior" is the Decorator Pattern. You have one decorator per
behavior, and you mix and match by adding the decorators that are
applicable. The advantage of decorators are that each class is a little
more insulated from changes in other classes, I think. The disadvantage
is that removing a behavior is more difficult (you have to unwind the
stack of decorators, and make a new stack, skipping the decorator you
want to remove).

Your strategy pattern idea seems to make replacing/removing a behavior
easier, but also (to me) seems to require a bit more complexity. Trade
off, I suppose, depending on which operation seems more important to
make easy and straightforward.


This is kind of the upside down version of "Prefer Composition over
Inheritance". You're still preferring Composition over Inheritance, but
the main entity doing the preferring is what would have been the Base
Class (rather than the Derived Class)


Decorators use composition too, just wanted to point that out.
 
D

Daniel Pitts

markspace said:
That's interesting. The classic solution to "mixing and matching
behavior" is the Decorator Pattern. You have one decorator per
behavior, and you mix and match by adding the decorators that are
applicable. The advantage of decorators are that each class is a little
more insulated from changes in other classes, I think. The disadvantage
is that removing a behavior is more difficult (you have to unwind the
stack of decorators, and make a new stack, skipping the decorator you
want to remove).
I don't see how decorators are any more insulated than strategies.
Your strategy pattern idea seems to make replacing/removing a behavior
easier, but also (to me) seems to require a bit more complexity. Trade
off, I suppose, depending on which operation seems more important to
make easy and straightforward.
It requires minimal complexity, IMO, compared to decorators. Decorators
do have there uses, but they the pattern I'm describing solves a
different problem.

I would only use Decorators in to extend behavior (performing the same
behavior, but modifying the input and/or output of the extended behavior).

If you are only modifying one behavior (method) of an object that has
many behaviors, then it decorating it would lead to a lot of
"pass-through" behavior.

Using strategies instead allows you to group related methods in one
interface, and only requires you to implement the strategies you care
about changing. You can combine Decorators and Strategies as well, by
having a Strategy be Decorated.
Decorators use composition too, just wanted to point that out.
Indeed they often do. However, in a different way than Strategy does.
The various strategy objects are composed in the model. Where as the
Decorators are composed of other Decorators or the Model object.
 
M

markspace

Daniel said:
I would only use Decorators in to extend behavior (performing the same
behavior, but modifying the input and/or output of the extended behavior).


Yes, that's primarily the use-case I was thinking of. Of course there
could be more complex interactions where decorators are not suitable.

> I don't see how decorators are any more insulated than strategies.


Primarily because they only do modify "input and output" and often only
deal with one public method at a time, I think they're more encapsulated
than certain other types of composition.
 
R

Roedy Green

Since the 'abstract' keyword works, and reflection is both messy and slow,
eschew reflection.

Granted, in this particular case, but for similar but more complex
problems, run-time checking may be the way to go.

It very rare you need to switch on the class of something in Java. It
almost invariably means you missed an opportunity to solve the problem
with OO.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"I mean, source code in files; how quaint, how seventies!"
~ Kent Beck (born: 1961 age: 48), evangelist for extreme programming.
 
R

Roedy Green

Also, asserts are (and should be) OFF most of the time.

An assert on program structure needs to be on only once.

I am not so sure about turning asserts off. Why?

1. a clever compiler optimises them out or makes them low overhead.

2. If things blow up at a client site, you want all the hints you can
get.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"I mean, source code in files; how quaint, how seventies!"
~ Kent Beck (born: 1961 age: 48), evangelist for extreme programming.
 
L

Lew

Roedy said:
An assert on program structure needs to be on only once.

I am not so sure about turning asserts off. Why?

That is their purpose.

The idea is that once you've proven the invariants, there's no need to keep
proving them except when the code changes. The code doesn't change in
production, by definition, it changes in development.
1. a clever compiler optimises them out or makes them low overhead.
Evidence?

2. If things blow up at a client site, you want all the hints you can
get.

That's what exceptions are for. And you can turn assertions on at the
production site, at will, class by class, when you need those hints.

The nature of invariants is that they're, well, invariant. Unlike exceptional
conditions, they don't change from run to run. Once you lock them down, turn
off the assertions. If you goofed, that's on your shoulders; then you have to
turn them back on (perhaps partially) and correct your mistake before you turn
them back off again.

It's a common mistake to think assertions are exceptions. They aren't.

Part of the reason for that mistake is that people don't analyze algorithms in
terms of invariants enough. When you look at an assertion in the code, it
often states the "obvious", as in:

public void setLittleRabbit( Foo foo )
{
if ( foo == null )
{
throw new IllegalArgumentException( new NullPointerException(
"foo == null" ));
}
this.littleRabbit = foo;
assert this.littleRabbit != null;
}

This in turn allows the set invariant postcondition to be a get.. invariant
precondition:

public Foo getLittleRabbit()
{
assert this.littleRabbit != null;
return this.littleRabbit;
}

Now, should someone subclass or alter this class and fracture the invariant,
the asserts will raise the salute. Since they're turned on in development and
all, you know.
 
R

Robert Klemme

An assert on program structure needs to be on only once.

I am not so sure about turning asserts off. Why?

1. a clever compiler optimises them out or makes them low overhead.

They cannot be optimized away by the compiler because enabling and
disabling them is a function of the JVM - not a compile time option.

Regarding the overhead: depending on the algorithm needed to verify
assertions they can take considerable runtime. This is nothing you want
to invest all the time. I have more than once done something like

assert classInvariant();

private boolean classInvariant() {
// complex calculation that returns true or false
}

As an example think of a class which contains a collection where only
objects with certain properties are allowed. The invariant checking
method might have to traverse the complete collection (which could be
large) and test every single object. Whatever optimization you are
going to make, you won't get this really fast.

The nice thing about this is - and that's where the smartness lies -
that the runtime won't even execute method classInvariant() at runtime
if assertions are off for that class.

As Lew excellently explained: assertions are to be used during
development and test phases - not in production.

Kind regards

robert
 
R

Robert Klemme

the JVM is the compiler ... its java  runtime is compiletime

Roedy did not mention JIT. When I read "compiler" without further
qualification in a Java forum this translates to "Java compiler".
Strictly speaking JIT is purely optional while you always need a Java
compiler to get bytecode from your sources.

Anyway, that whole discussion is meaningless with regard to Roedy's
statement that you want assertions on all the time. This is abusing
assertions and not making best use of them.

Cheers

robert
 
J

John B. Matthews

Mike Amling said:
A certain class is used 80% of the time as is, and is extended 20% of
the time. I want to ensure that each subclass overrides a certain
method. The only way I can think of to do this is to put code in the
base class's constructors, and when the class being constructed is
not the base class, check that getDeclaredMethod does not throw a
NoSuchMethodException.
Does anyone know of a more efficient way? At compile time, maybe?

I'm not sure if this is useful, but it reminds me of "When an Abstract
Class Implements an Interface" [1]:

interface Interfaccia {
String metodo();
}

abstract class Basso implements Interfaccia {
// anything except metodo()
}

class Estesa extends Basso {
// implementation of metodo() required
public String metodo() {
return "ciao";
}
}

[1]<http://java.sun.com/docs/books/tutorial/java/IandI/abstract.html>
 
D

Daniel Pitts

Robert said:
Roedy did not mention JIT. When I read "compiler" without further
qualification in a Java forum this translates to "Java compiler".
Strictly speaking JIT is purely optional while you always need a Java
compiler to get bytecode from your sources.

Anyway, that whole discussion is meaningless with regard to Roedy's
statement that you want assertions on all the time. This is abusing
assertions and not making best use of them.
Assertions are another way of catching bugs in production. If your
assertions are causing a large performance penalty, then you can
consider disabling them in production, or adjusting them to make more
sense. Otherwise, leaving them in and on is considered a best practice.

You don't need to test for all invariants everywhere, especially
invariants that would cause an exception anyway (such as a collection
must only contain objects of a certain class. That will be caught by a
ClassCastException, which is a built-in assertion you can not disable)

In other words, assertions should be used where failure of the invariant
may change the output of the program in subtle ways, not where failure
will itself cause an exception.
 

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

Forum statistics

Threads
473,981
Messages
2,570,187
Members
46,729
Latest member
ScarlettJe

Latest Threads

Top