There are two different ways to create a subclass in OOP. Java treats the subclass and the superclass as the same object. If the subclass calls a method on itself, it may go to the superclass first. This is a valid way to do things, but it can be dangerous and confusing.
Another way to create a subclass is to create two objects: the superclass and the subclass. The subclass has a reference to the superclass, but they are not the same object. If the subclass doesn't override one of the superclass's methods, then it implicitly proxies the method call to the superclass. If the superclass calls a method on itself, then it goes to itself rather than the subclass.
The difference between the two approaches is whether you want your class implementation to be open to extension (monkey-patching). Allowing class inheritance (Java's approach with the virtual methods) means that subclasses can override methods you define. It can be convenient, but it can also be a foot-gun. Class composition (proxies) prevents monkey-patching by subclasses.
Java makes a lot of common classes final (e.g. String and Optional) so that it can avoid this. As I understand it, it's also got a lot of pixie dust to predict this some of the time, but then you can't rely on it.
Final classes encourage the creation of utility classes, which can often become a problem.
One downside is that every method now requires following a pointer, which is pretty awful for performance on modern hardware.