Please do not use the term “class” in this way. A class describes the behavior and structure of an object. You are talking about objects (an instance of a class). This is a fine but very important difference. If you mix the terms you quickly confuse the reader and yourself.
In terms of classes there is no problem in creating multiple instances of the same class. That is what they are used for. Otherwise you could use a module to create a singleton (you can have just one module of the same name).
Typically you always store a reference to your objects (class instance) into a variable. If you want to use a list, several variables, or other container depends on your situation. There is no problem to store the reference to the same object in multiple variables either.
controller.owner is just a way to get the reference to the object of class KX_GameObject from the context. You can get such references from several other sources including properties, modules, logic bricks.
objectFromProperty = controller.owner["myObject"]
objectFromModule = myModule.myObject
objectFromActuator = mySteeringActuator.target
objectFromObject = myObject.anotherObject
As you do not told us how your classes are supposed to interact with the controls, we can’t give you any advice on that.
As classes define the behavior of multiple objects, these objects will behave the same. That does not mean the all do the same thing at the same time. It means they behave the same under the same circumstances. Objects typically contain internal data which define the objects current state. These data usually is different between the different objects, while the behavior (the code) is the same.
A shared class also defines a shared interface of the objects. That means if one object has a specific attribute, the other object has the same attribute too. This makes it easy to treat such objects all the same.
Your “Player” class implements a method “run()”. That means you can call run() on any of the objects that inherit from class Player:
for player in collectionOfPlayers:
The user of the players does not need to care how “run()” is implemented. He just needs to know it is callable. He does not even need to know if it is player one or player two or player “I’m the good of this game”. They all can run() -> do it.