From the Named Credentials documentation, an important summary:
By separating the endpoint URL and authentication from the callout definition, named credentials make callouts easier to maintain. For example, if an endpoint URL changes, you update only the named credential. All callouts that reference the named credential simply continue to work.
Named Credentials insulate your code from specific endpoint URLs and from authentication details, and also provide secure storage for secret authentication parameters. The latter is a capability that is otherwise only possible by using a Protected Custom Setting in a managed package, which not every org has the capacity or inclination to do. Otherwise, you're stuck with storing highly sensitive authentication parameters, such as OAuth refresh tokens, in locations where anyone with View Setup and Configuration permission can get at them. Named Credentials makes that security problem go away.
Put shortly, they abstract away a lot of complex, difficult, and risky (from a security standpoint) implementation details so that your code doesn't have to handle them, and they improve the maintainability and security of your outbound connections.