The question answers itself if we think about behavior instead of state, and we should. Inheritance is motivated by "doing the same thing, but differently" or having additional functionality for various subtypes. Perhaps the designers have a good notion that ParkingSpot and Vehicle behavior will expand and evolve. Maybe for the sake of learning ...
You are correct that right now the derived classes are superfluous, because their only difference is one specific enum value, which is labeled the exact same way. You could omit either the enum or the derived classes, and nothing would change.
However, that conclusion might change when there are more differences than just the enum value.
For example, if the ...
Room has Collection of Keys
a natural piece of code. Although a better name would be addKey().
Given where the collection lives, there are drawbacks to using:
Because now, for the collection to work RoomKey has to turn around and call room.assignKey(this). Which is a little busy, ...
In an aggregate class.
Example: When you drive a car, you do not have to worry about moving the wheels forward, making the engine combust with spark and fuel, etc.; you are simply driving the car. In this context, the car is an aggregate of several other objects
I don't know the flow of the uml that you made, maybe my answer can help you, if there is a roomkey and there must be a relationship between fields that are the same as the data type, first see if they match, the answer is correct if the referee and the match have a connection