Can you give an example of why exactly a Java abstract method cannot exist in a non-abstract class?

1.3k Views Asked by At

I'd like a real-world type example that illustrates why exactly a Java abstract method cannot exist in a non-abstract class.

I appreciate the reasons why that can't happen - abstract classes forcing implementation of any abstract methods contained in them - but an understandable concrete example would really help me reason it out in my head, many thanks.

5

There are 5 best solutions below

1
On BEST ANSWER

One of the key differences between an abstract class and a non-abstract class is the fact that you cannot create an instance of an abstract class. This prevents a situation where a method with no definition gets called.

So if we had the following abstract class:

abstract class Elephant {    // abstract class

    public String getName() {
        return "Ollie";
    }

    public abstract void walk();   // abstract method

}

Then the following would be illegal:

Elephant e = new Elephant();   // error

Because Elephant is abstract and it cannot be instantiated.

But say for argument sake, that we make Elephant non-abstract but it is allowed to still have the abstract method walk(). i.e. we change the definition of Elephant to:

class Elephant {    // non-abstract class

    public String getName() {
        return "Ollie";
    }

    public abstract void walk();    // abstract method

}

Now what should happen if I do the following:

Elephant e = new Elephant();   // legal since Elephant is non-abstract
e.walk();   // oops, we didn't define this anywhere

Java compiler won't allow this. You could argue that there are other ways to handle a situation like this, but this simply how the Java language has decided to implement the feature.

0
On

Another way of looking at this "why do I have to provide implementations of my interface?"

And the answer is because interface methods are implicitly abstract. So you must provide an implementation (or an empty body). Otherwise, you will get a compiler error because there is no method body and thus no legitimate method to call (the JVM would not know how to handle it - for a non void return type, what would it do?).

Now you if you declare that same class as abstract, no implementation is required. Then you are reduced to your earlier question, for which the answers are the same. Abstract methods can't be called so it makes no sense to allow the classes that contain them to be instantiated.

0
On

Foreword: I tried to make it simple and logical but this may not be an exact logical explanation but this will surely help you reason it out in your head, just know there are rules that you have to follow. In every language you may come across such rules that may seem little confusing, questionable.

Let's try to understand it like this:

A method without definition is incomplete, using an abstract(incomplete) method in a non-abstract(complete) class will add incompleteness to that class and will make that class incomplete. Now you cannot instantiate the class because it is incomplete(abstract).

And this doesn't make sense because you can use abstract class for this, why turn a non-abstract class into abstract. That's why it is not allowed.

But if you want to do something like this, you can add methods with empty definition to non-abstract class.

0
On

An abstract class means that the class can't be directly instantiated. If a class has an abstract method, then it can't be directly instantiated since there would be no definition for that method. Therefore, any class with an abstract method IS an abstract class that can't be instantiated. Java simply makes you label it as such.

0
On

Like an abstract method in a class, methods from an interface (which are implicitly abstract) allow to model an abstraction. Something that is related to multiple types, but yet every single part acts differently.

Consider a simple vehicle, which can drive(), that´s one thing common to vehicles.

public interface Vehicle {
    void drive();
}

Now, you cannot create a Vehicle by itself: Vehicle v = new Vehicle(). Consider the task to build something that can drive. You just care that it can drive, irrelevant of how excactly it is done. You talk of an abstraction, but you always need a concrete implementation, something that is actually capable of doing so. That´s why you cannot instantiate an abstract class. It is incomplete, missing some required part that is abstracted.

Therefore, each vehicle drives differently, as the following implementations demonstrate:

public class Car implements Vehicle {
    public void drive() {
        if(isEngineTurnedOn()) {
            GearState state = getCurrentGearState();
            if(state == GearState.BACKWARDS) {
                // ...
            } else {
                engine.setSpeed(currentSpeed);
            }
            // ...
        }
    }
}

public class Boat implements Vehicle {
    public void drive() {
        if(isEngineTurnedOn()) {
            rotor.setAngleInDegrees(currentAngle);              
            rotor.setSpeed(currentSpeed);
            // ...
        }
        // ...
    }
}

Then, if you ask again for something that can drive, you can hand the caller a new Car(), which is capable of doing so. Since the caller is just interested in drive(), you could have handed him a new Boat() as well.