Refactor serialization/deserialization into class definitions

The goal here is to move the logic for serialization and deserialization on to the class definitions. The `ObjectExporter` and `ObjectLoader` classes still exist as thin helpers, that call out to the serialization methods implemented on the Classes themselves. This breaks up responsibility, and allows custom classes to provide their own serialization methods. Updates #4609