dabadaba
dabadaba

Reputation: 9512

How to declare abstract method in non-abstract class

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:

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

Answers (5)

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

toKrause
toKrause

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

yugo
yugo

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

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

Mena
Mena

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

Related Questions