He's definitely right. Java has always been this way. Or at least since the first language specification; I confess I'm not so familiar with what came before.
An example of a use for this is
KeyAdapter - or any of the abstract ***Adapter classes that implement
EventListener. All three methods of KeyAdapter are concrete, not abstract. And they all do nothing at all. The idea here is that you can use this to quickly write a KeyListener that only reacts to the events you want to react to - because you only override the methods that you want to do something with. The remaining methods are already overridden to do nothing. There was no need for any particular method in KeyAdapter to remain abstract; they all have a reasonable default behavior of "do nothing". So there are no abstract methods here. And yet, the class is useless unless you override
something. So the class is declared abstract, even though no one method is abstract.