Player classes can be changed and swapped at runtime. They change things like the player's speed, height, the weapons the player spawns with, what happens when they die, what happens when they spawn etc.
Imagine a Team Fortress 2 gamemode. You want the Scout to run faster than the HWG. So you would design different classes for them. When a player spawns you set their class - and they have those attributes.
Player classes can be derived. So your gamemode can define a shared common class for all of your players and derive different classes from there.
You can find a list of default fields here.
Traditionally if you wanted to do this in your gamemode you would either code a system similar to this, or you would end up with a bunch of if/else blocks in your spawn functions.
This system cleans that up by making it unified and object orientated.
Setting a player's class is done easily. You only need to do it serverside.
This is commonly done in the PlayerSpawn gamemode hook - but you can call it anywhere you want.
SetPlayerClasswill flag that player as the desired class, however, it will not affect the player's entity until
player:Spawn()has been called and the player's entity is refreshed.
The player class itself doesn't need much comment. It should be mostly self explanatory.
The class below creates a new player class called "player_custom", which is derived from "player_default". The player spawns with a pistol.
These player class functions are usually housed in gamemode/player_class/ - and they do not get loaded automatically. You should load it in your shared.lua gamemode file. And they should be loaded in the right order - so that base classes get loaded before their children.