Let's say that I have an interface IMazeRoom
This interface has a function getAdjacentRooms()
Furthermore, Mazerooms have to be instanciated as IMazeRoom room1
etc.
(All of the above cannot be changed)
Let's say these classes are implementing the interface:
TrapRoom, FreeRoom, MobRoom, TreasureRoom
I want to the following functions/variables to be used in all of those subclasses
Players[] playersInRoom, setSize(), isAdditionValid(Player p)
I want to use inheritence with the three functions/variable above without modifying the interface, or duplicating the code throughout the four subclasses.
What I have tried so far
Making an abstract interface MazeRoom which implements IMazeroom, and is implemented by the four subclasses. This does not work as a constraint of this project is that the rooms have to be instantiated as IMazeroom room
and doing this would lead to instantiation Mazeroom room
If I wanted to use the new functions meantioned above. Also IMazeRooms cannot be modified.
Ideas
I could probably just use another interface with the functions I want to include, which would be implemented by IMazeroom, but this seems weird as this constraint should be here to teach me something, and I do not see the value in just using another interface. Furthermore, using another interface would not really cut down on code duplication, I am looking for something more like a abstract class
(The above is a completely different example from my homework task, as I want to attemp the task on my own)
Edit : Since we cannot change the interface, you can use a DefaultRoom
class that implements IMazeRoom.
public class DefaultRoom implements IMazeRoom {
protected Players[] playersInRoom;
/* your standard method implementations */
public boolean isAddtionValid(Player p) {
...
}
}
public interface IMazeRoom {
...
}
Since you have to instantiate it via IMazeRoom myIMazeRoomObject = new DefaultRoom()
, as long as you know which kind of Room you are handling, you can simply cast it back:
try {
DefaultRoom myRoom = (DefaultRoom) myIMazeRoomObject;
} catch(ClassCastException ex) {
// we didn't get a DefaultRoom object and now we have to handle that
}
Sidenote: The important thing to note is, that the interface only implements the necessary method getAdjacentRoom
, as such it only constitutes information to some (arbitrary) layout that relies on getAdjacentRooms()
. Your secondary constraints (immutable interface + instantiation) make it necessary to circumvent something that shouldn't happen with proper OO architecture.
You can seperate the common concrete implemetation into a abstact class and keep the interface.
Rough example based on "I am not allowed to change the interface though":
IMazeRoom:
public interface IMazeRoom {
Set<IMazeRoom> getAdjacentRooms();
}
Common concrete implemetation:
public abstract class CommonRoom {
private final int size;
private final Set<Player> playersInRoom;
private final Set<IMazeRoom> adjacentRooms;
protected CommonRoom(int size, Set<Player> playersInRoom, Set<IMazeRoom> adjacentRooms) {
this.size = size;
this.playersInRoom = playersInRoom;
this.adjacentRooms = adjacentRooms;
}
public int getSize() {
return size;
}
public Set<Player> getPlayersInRoom() {
return playersInRoom;
}
public Set<IMazeRoom> getAdjacentRooms() {
return adjacentRooms;
}
public boolean isAdditionValid(Player player) {
// Some kind of implementation returning true or false...
return !playersInRoom.contains(player);
}
}
TrapRoom:
public class TrapRoom extends CommonRoom implements IMazeRoom {
public TrapRoom(int size, Set<Player> playersInRoom, Set<IMazeRoom> adjacentRooms) {
super(size, playersInRoom, adjacentRooms);
}
}
TreasureRoom:
public class TreasureRoom extends CommonRoom implements IMazeRoom {
public TreasureRoom(int size, Set<Player> playersInRoom, Set<IMazeRoom> adjacentRooms) {
super(size, playersInRoom, adjacentRooms);
}
}
... same implementation as TreasureRoom for additional rooms.
Comment: Now all rooms are treated as IMazeRoom...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.