More than just "in practice", it might be worse than copy/paste. Richard Gabriel nailed it in the 90s when he identified inheritance as a form of compression, not reuse, forcing the programmer to have to understand every class under inheritance to understand any part of it:
Compression is a little dangerous because it requires the programmer to
understand a fair amount about the context from which compressed code will
take its meaning. Not only does this require available source code or excellent
documentation, but the nature of inherited language also forces the programmer
to understand the source or documentation. If a programmer needs a lot of context
to understand a program he needs to extend, he may make mistake because
of misunderstandings.
(from Patterns in Software, which is a really deep if long-winded book)
Sure, you can clone Foo into Bar and change one thing in Bar. But what happens when you need to change functionality common between Foo and Bar? Oh right, you have to change the same thing in two places now. Doesn't seem so smart anymore...
This is why Go has standalone functions and interfaces. You can easily share logic between types without having the types be the same thing.
The biggest problem with inheritance is that it's a lot like monkey patching (except in production)... the rest of the base class's code expects method X to do ABC, and you've just swapped out the implementation to do LMNO ... and if that never bites you in the ass, you're luckier than most OO programmers I know.
This is the big insight. Instead of trying to inherit code, figure out what that code does that interesting, and allow that code to do the interesting things without being inside the class. For example, imagine your class has a "WriteToFile" method. Instead of that, it should just have a method to return its representation, delegating the responsibility of writing to a file to something else. (Of course, the fact that a file can be written to should also be one of those "interesting things", and the thing that writes shouldn't care that it's backed by a file.)
Instead of
foo.WriteToFile("/tmp/foo")
You might write:
file.Write(foo.Representation()).
I promise that most inheritance in the real world is attempting to reuse something like "WriteToFile". "I wouldn't want to copy-paste the file-writing code, so I'll inherit from something that can write itself to the file." No. Don't do that.
"Give me an object like Foo, but with this one little thing changed."