A simple explanation inevitably omits information. Whether the omitted information would have been useful to you is something only you can judge, which means you end up having to review the details anyway. Hadley Wickham's Advanced R is worth Googling, and don't forget to RTFM.
In a nutshell, S3 builds on free-typed lists of object members, with a class attribute of character type that is matched up with standard functions serving as methods using a naming convention based on pasting the method name with the class name. Generic method dispatch is determined by the class attribute of the first argument to the function. It is lightweight and easy to work with, but not type-safe, so don't shoot yourself in the foot.
S4 uses a special class data type with member "slots" accessed using a special "@" notation, created using a "class factory" approach. All methods and members are type-safe (cannot use the wrong data type with them). Generic method dispatch is according to the whole argument list type signature. I have found it to be noticeably slower than S3, but that result likely depends strongly on your use case.
If you simply must have something similar to Java/C++ class inheritance structure with pass-by-reference semantics, you might want to consider the R6 package, but the best choice is usually the simplest, S3.
Sent from my phone. Please excuse my brevity.