Interfaces are types, and concrete classes implementing them are subtypes.
OTOH, it's probably easier to avoid LSP violations with interfaces than concrete supertypes.
> Is there a good reason to have a class hierarchy in modern programming?
Well, implementation inheritance facilitates code reuse; there's some ways to do that that aren't traditional class heirarchies, but they mostly seem morally equivalent to multiple inheritance with partially-abstract base classes. Ergonomically, though, I think some of them don't do as much to encourage inappropriate subytyping or implementation sharing compared to classical purely-class-based inheritance.