|I dont really understand the purpose of getters and setters either? why not just make the data public?|
It's about separating out the interface, which should adopt the semantics of the services your class is providing to the code which uses it, from the implementation details, which should be whatever they need to be to get the job done.
The implementation details may change as you develop the class, but the purpose of the class should remain stable, which means that the interface can remain stable, which means the interactions of the rest of the code with the class can remain stable.
If your interface is just a bunch of getters and setters for each data member, then you've almost certainly not thought properly about the design of your class and what it's actually for.
Really, getters and setters are useful for tutorial purposes. They introduce the idea of hiding the implementation details behind an interface, in a simple-to-understand way. It's a stepping-stone towards learning how to write a good interface.
The problem is that many people teaching this stuff don't then go on to deepen their pupils' understanding of what makes a good interface.