It's not unfortunate happenstance, it's by definition.
Dynamic dispatch is the defining feature of object-oriented programming. In dynamically typed languages such as Smalltalk, you can get there with duck typing. But a statically typed language needs a statically typed mechanism for dynamic dispatch, and that requires some way of saying, "Y is a particular kind of X, so all members of X are also in Y." Which is - again by definition - inheritance.
You could remove - or refuse to use - the inheritance (or, equivalently for some purposes, duck typing). But that would also prevent the use of dynamic dispatch, so what you're doing would bee be procedural programming, not OOP, even if you're using an object-oriented language to do it.
> Dynamic dispatch is the defining feature of object-oriented programming.
Message passing is the defining feature of object-oriented programming. Dynamic dispatch can be achieved using message passing, but message passing is more than dynamic dispatch.
Ultimately, static typing is incongruent with object-oriented programming. Messages are able to be invented at runtime, so it is impossible to apply types statically. At best you can have an Objective-C-like situation where you can statically type the non-OO parts of the language, while still allowing the messages to evade the type system.
Dynamic dispatch is the defining feature of object-oriented programming. In dynamically typed languages such as Smalltalk, you can get there with duck typing. But a statically typed language needs a statically typed mechanism for dynamic dispatch, and that requires some way of saying, "Y is a particular kind of X, so all members of X are also in Y." Which is - again by definition - inheritance.
You could remove - or refuse to use - the inheritance (or, equivalently for some purposes, duck typing). But that would also prevent the use of dynamic dispatch, so what you're doing would bee be procedural programming, not OOP, even if you're using an object-oriented language to do it.