My Entity class has x & y locations, an image, an enum of EntityType which tells me if it's a player object, opponent object, player projectile, opponent projectile etc. My entity class also has hit points so I know how much damage it can take. Entity does not move. About the only time I use this base class by itself is if I want to place an object on the background. That object doesn't move and usually has no collision properties. Entity has getImage() doUpdate(container, game, delta) and doRender(Graphics g) which all other entities inherent. It also has some booleans such as isCollidable and isVisible so I can turn collisions on and off and make them visible or not.
The Entity class also has my collision rectangles. Normally it's just the rectangle of the image but I also have a list of rectangles which I use for oddly shaped sprites. Rectangle collision detection is fast and easy. Java's Rectangle2D.Float extends RectangularShape which has the method public boolean intersects(Rectangle2D r) which is fast and precise enough for my needs.
Then I have a MovableEntity object which extends Entity. That has dx/dy speed, acceleration rate , deceleration rate and max speed.
I have a Startable entity which extends MoveableEntity. This is a class where I can set my dx/dy but not have the entity move until I give it the start command. This way I can set up objects offscreen and start them moving into the screen when I want to.
I also have ControllableEntity which extends MoveableEntity. This entity can be bound to keyboard or game controller events and can change the dx/dy, speed, and acceleration of the entity.
I recently added AnimatedEntity which will go between Entity and MoveableEntity. This way I can animate any of my entities as I do other things as well.
I created a Projectile class which extends MovableEntity. The Projectile knows if it has moved offscreen and if so places itself back into the bullet pool. Things which extend Projectile overload the image in the base class Entity with a static image so all the projectiles of a single type are using the same image in memory.
I place different entities in different Arraylist. My GameLevel class has these list:
private ArrayList<Entity> backgroundEntityList = new ArrayList<Entity>();
private ArrayList<Entity> midLevelEntityList = new ArrayList<Entity>();
private ArrayList<Entity> opponentEntityList = new ArrayList<Entity>();
private ArrayList<Entity> postOpponentEntityList = new ArrayList<Entity>();
private ArrayList<Entity> playerEntityList = new ArrayList<Entity>();
private ArrayList<Entity> postPlayerEntityList = new ArrayList<Entity>();
private ArrayList<Entity> hudEntityList = new ArrayList<Entity>();
private ArrayList<Entity> messageEntityList = new ArrayList<Entity>();
private ArrayList<Entity> playerProjectileEntityList = new ArrayList<Entity>();
private ArrayList<Entity> opponentProjectileEntityList = new ArrayList<Entity>();
These list allow me , for example, to draw all the background images, player images, opponent images, etc all in correct Z order. The 2 projectile list in particular make it easier to pool bullets. The postPlayer and postOpponent list allow opponent images to come out of caves which the player can fly over, or for the player to fly under a bridge.
The HUD list always paints next to last so the HUD (Heads Up Display) is on top of everything.
The Message list paints last. I use this for menu items and messages which need to paint on top of everything.
In my game loop I walk through every list in order and call the doUpdate of every entity. Then I do the same thing with doRender and it all works by itself.