One of the best things Java brought to OOP was the idea of the interface. The idea that we can define the functional shape of the object we need, without defining anything else about it. I rarely find the need to use inheritance over interfaces in Java, especially when thinking in terms of Liskov and proper substitutability. The cases where inheritance is the correct decision is actually very rare, compared to the cases where it's simply a convenient but ill-guided method of passing common data and functions around. As an easy example, the fact that `java.io.OutputStream` is a class instead of an interface. In my opinion, that was a bad decision made purely to provide default implementations of the `write(byte[])` and `write(byte[], int, int)` methods. It would have been better as an interface. I really like where Rust went in this regard with traits, especially the ability to define them external to the type itself.
This wasn't something Java brought to OOP, it was borrowed almost verbatim from Objective C (protocols). You can google your way to Java's designers specifically mentioning this as a direct influence.
Perhaps I should have said "popularized by Java". It's also not something that couldn't have been done in C++ by creating classes which consist purely of abstract functions, since C++ allows for multiple inheritance.
That's probably true, although I'm not sure it's a very meaningful distinction as you can make a fairly reasonable argument that Java popularized OOP in general or at least, put it in the mainstream. I did find the post I was thinking of
Among other things, it gives a bit of an inkling of the attitudes of the people working on then-current and new OOP systems and languages towards C++ at the time.
But, yes, that sort of thing quickly becomes talmudic interpretation of 'what is true oop' :)