Reputation: 9512
I want to declare a couple of abstract methods (so the implementation is required in the classes that inherit from this one) to fit my situation, which is:
I am making a puzzles solver program. So far I have 3 packages:
games.puzzles
games.puzzles.rivercrossing
games.puzzles.rivercrossing.wolfgoatcabbage
I don't want to get too specific but in the games.puzzles.rivercrossing
package I have two classes that represent a bank and a state: GenericBank
and GenericState
.
Now, they define some behavior, but there are some methods that the classes that inherit from these must have, like move()
to move one element from one bank to the other or isPermitted()
and isFinal()
to check the states.
For example, in the last package I have the WolfGoatCabbageGame
class and it must have its own Bank
and State
classes which will inherit from the generic ones. These particular Bank
and State
classes must implement the methods I mentioned above, for example in the Wolf, Goat and Cabbage game, to check if the goat and the wolf are not in the same bank, etc.
So initially I declared the generic classes as abstract
, and these methods to be implemented abstract
as well:
public abstract class GenericBank {
// more members ...
public abstract boolean move(Element element, GenericBank dst);
// more members...
}
public abstract class GenericState {
// more members...
public abstract boolean isPermitted(GenericBank bank);
public abstract boolean isFinal(GenericBank bank);
// more members...
}
And this looked like it'd work until I found out I had to instantiate GenericBank
and GenericState
objects, which of course can't be done if these classes are abstract.
So I had to remove the abstract
qualifier from the classes.
So... what can I do? How can I declare abstract
methods (or achieve the same behavior) in a non-abstract
class?
Upvotes: 2
Views: 26401
Reputation: 8245
You cannot, the very definition of an abstract class is that it has abstract methods.
What you can do, is define default behaviour, that can be overruled by subclasses.
However, I would carefully consider your class hierarchy before doing this. The fact that you need to instantiate some classes before their actual implementations are known, suggests that your design may need re-thinking.
If you're going to re-design, you will want to look at the time of instantiation - and underlying that, the reasons for instantiating.
Right now, you want to use some of the common behaviour of a class, before the actual instance of that class is known.
It goes a bit beyond the scope of answering the question, but: consider explaining the design of the code to a friend. Or to a rubber duck. This may help you to find a fresh approach.
Upvotes: 0
Reputation: 512
You could replace the abstract methods with empty methods that do nothing and return the default value of their respective return type (and, if necessary, make it part of the generic classes contract, that subclasses must override these methods).
Alternatively, you could keep your abstract Generic*
-classes and add Null*
-classes with abovementioned empty implementations, following the Null object pattern.
Upvotes: 1
Reputation: 198
Remove the abstract qualifier and add a empty body, or throwing some runtime exception.
Or instantiate these generic classes as anonymous sub classes
Upvotes: 0
Reputation: 15941
How to declare abstract method in non-abstract class?
Answer: You can't. It's kind of the definition of abstract. It's the same reason you can't instantiate an object as an abstract class.
Either:
A) You need to use Interfaces
B) Leave the methods empty in the parent class:
//technically this needs to return a value, but it doesn't need to *do* anything
public boolean isPermitted(GenericBank bank){ return false; }
C) Refactor your code so that you aren't instantiating abstract objects. I cannot advise how to do this as you haven't provided any code regarding this.
Upvotes: 10
Reputation: 48404
You cannot declare abstract
methods in a non-abstract class, final dot.
That would simply defile the concept of abstract
methods.
What you can do is have your class hierarchy implement interfaces dictating the required methods to implement.
If you found your formerly abstract
classes were actually better designed as concrete classes, do convert them to concrete classes and implement the methods, even with a default, general implementation.
You can then fine-tune the overrides in your child classes.
Upvotes: 0