简体   繁体   中英

A class with empty methods vs abstract class?

Why can't we have a normal class with empty methods in it, and then sub-classes which override the base-class' empty methods, instead of an abstract class? For example:

class Base {
    
    void methodA() {
        //empty
    }
    
    void methodB() {
        //empty
    }
}
    
class Sub extends Base {

    void methodA() {
        //implementation
    }
    
    void methodB() {
        //implementation
    }
}

I assume that what you really ask is "Why do we need abstract classes/methods, when we can just have a normal class with empty methods instead".

And the answer to that question is that with the abstract method, the sub class MUST provide an implementation. If the method is not in parent is not abstract, then nothing requires the sub to provide an implementation at all.

This is important in cases where an empty implementation of a method makes no sense, because then the compiler can give you an error, because your sub class have not implemented all required methods.

In your specific case, where you have 2 methods which don't return anything, it may be alright to do what you're doing. It's kind of flirting on the edges of the null object pattern , but not quite. There's nothing stopping you from doing it that way; it will compile. In some designs, it may even be a good choice. Your example is too contrived to say whether or not it's a good idea.

Suppose you have a method which returns a value, though. You can't just put a comment //do nothing because you need a return to satisfy the compiler. So you add a sentinel value. This is pretty error prone, as it relies on callers being aware of the values which have special meanings. It may even be the case that no suitable sentinel value even exists, if the set of genuine results contains every possible value.

class Base {
    void methodA() {
        //empty
    }
    
    int getFoo() {
        // Don't do this, just an example
        return -1;
    }
}

Someone might instantiate new Base() and not realise that their code is destined to be useless, and that the class's author intended for them to instantiate Sub or another child class. They might not know they're supposed to check sentinel values, etc.

It would be better in this case if they couldn't do that. It would be better to mark Base as an incomplete implementation, and tell the compiler that it must be completed to be any use. This is precisely what abstract classes are for.

By marking a class as abstract, you are telling the compiler that users are not allowed to instantiate this class because, for whatever reason, doing so does not make sense.

By marking a method as abstract, you are telling the compiler that a child class must provide an implementation in order to itself be instantiable (the child class could also be abstract, kicking the can down the road to child class of itself to provide an implementation).

abstract class Base {
    void methodA() {
        //empty
    }
    
    abstract int getFoo();
}

TL;DR your one specific example does not prove that abstract classes have no utility.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM