Why do multiaddrs have a byte representation?

Why are they done in string and byte representation formats?

Why not just a string?

Because you can encode bytes into strings and vice-versa. If they were strings people would be discussing how to best encode them to bytes instead of the contrary.

Also because hash functions operate on bytes, not strings, and computer programs in general operate with bytes, not strings.