Mostly, it's for two main reasons:
1) Functions aren't variables and they are not interchangeable
2) Functions support a lot more things than variables do. Actually variables don't support any functionality, just their (convenience) getters.
Functions and variables behave quite differently. You have to implement the interface's functions, which literally means that they have to have an implementation - they have to do something. A getter doesn't really do anything else than return the value of a variable.
For example your interface function balanceOf
: nobody says exactly how you should implement the function - it just needs to have the given signature and the rest is up to you. Nobody tells you it has to return any meaningful value - maybe you decide to always return 0
and it's totally fine from the interface's point of view. Or maybe you want to do complicated calculations - you can't do any of that with just a getter function.
I found someone else also having the same idea: https://github.com/ethereum/solidity/issues/3514
balanceOf
. There's nothing wrong with implementing the interface that way, but it seems that the Solidity compiler doesn't recognize that you have properly implemented the interface when you do it that way.