I suggest to keep a tile as simple as possible, like you do with only giving it an ID, perhaps a bool for collision or any other simple things to identify what type of tile this represents. A class like this should look like, (All pseudo code, i'm a C# guy but implementing this in java should be a breeze if you know the basics):
class Tile
{
public int baseID;
public bool Collision;
}
This is pretty much all you need to draw everything necessary and have collision working. You just build layers of these in this order from back to front from left to right from top to bottom. (It does not need to be in this order if every sprite fits within the tilesize.)
Tile[,] baseMap = new Tile[100,100]; //Put in all your backgrounds
Tile[,] objectLayer = new Tile[100,100]; //Put in all your objects
Tile[,] anotherObjectLayer = new Tile[100,100]; //Put more objects in a separate layer.
You would draw it like this:
for (int y = 0; y < mapheight; y++)
{
for (int x = 0; x < mapwidth; x++)
{
draw(baseMap[x,y]); //Obviously you need your implementation of ID to texture here.
//If your tiles are 32*32 you would draw it on x*32, y*32, width 32, height 32.
draw(objectLayer[x,y]);
draw(anotherObjectLayer[x,y]);
//Drawing it like this will result higher/further tiles to be covered by larger objects like tree's.
//You need to find out where the moving things are, like the player, to draw them on the correct [x,y] iteration.
}
}
If you need slightly different variables and parameters for a layer you are free to create another class for these. Maybe inheriting from the base tile class will do you good. Here is an example for a chest tile:
class Chest : Tile
{
//The baseID would be it's texture.
//The Collision can be used to have hidden chest or buried treasure.
int ChestItemID; //The item ID this chest holds.
List<int> MultipleItems; //For loot frenzy.
bool MonsterInABox; //For oldschool feeling
int Lock; //First get the key with this ID to unlock it.
}
Since this class inherits from tile it is perfectly fine to put this in one of the above layers so you do not have to create a complete layer arrays just for chests.
Next time make a new question for the collision issue since it is so different. Anyway, you glitch true since your tiles are probably 48*48 and this your character never steps on the tile with the collision on it. Therefor you should write a method that predicts what tiles your crossing. Depending on your needs you can check every pixel or just one step in between. Another option would be to calculate the next tile the player goes to remembering the first, with a tilemap like this it is very simple to check which tiles have been crossed between those points. First ask yourself if you need to move at speeds larger then your tiles, and what would be the maximum speed? If you just use the fast moving for debugging create a debug method for it.