Objective-C does have object methods, but they're dynamically typed: methods can come and go at runtime, method names can be constructed from strings, and there's no need to downcast an object of a superclass type to the subclass type before calling a method on that subclass. This design choice basically forces Objective-C into doing a hash table lookup and indirect dispatch for all method calls as a base case. This logic is encapsulated in the "objc_msgSend" function, which the compiler compiles all method invocations into a call to.
(If you're thinking "wow, that must be slow", you're right: objc_msgSend is very heavily optimized, but you can't beat one load from a fixed offset and an indirect jump as in C++ and Java. This is why Swift made the decision to abandon this model from the get-go. Other dynamic languages have ways to optimize this and eliminate the hash table lookup in most cases, but these techniques require self-modifying code, which Apple doesn't want to use; the only feasible solution for Apple's native language was to switch to a different semantics.)
Well, for Objective-C compatibility, and maybe for interfaces/protocols (depending on whether they use fat pointers or not), they need that capability. But Swift tries to push you into C++-like vtables when possible.
(If you're thinking "wow, that must be slow", you're right: objc_msgSend is very heavily optimized, but you can't beat one load from a fixed offset and an indirect jump as in C++ and Java. This is why Swift made the decision to abandon this model from the get-go. Other dynamic languages have ways to optimize this and eliminate the hash table lookup in most cases, but these techniques require self-modifying code, which Apple doesn't want to use; the only feasible solution for Apple's native language was to switch to a different semantics.)