简体   繁体   English

OOP - 接口继承抽象 class 替代

[英]OOP - Interface inheriting an abstract class alternative

Let's say that I have an interface IMazeRoom假设我有一个接口IMazeRoom

This interface has a function getAdjacentRooms()这个接口有一个 function getAdjacentRooms()

Furthermore, Mazerooms have to be instanciated as IMazeRoom room1 etc.此外,必须将 Mazerooms 实例化为IMazeRoom room1等。

(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.制作实现IMazeroom的抽象接口MazeRoom,由四个子类实现。 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.这不起作用,因为该项目的限制是房间必须实例化为IMazeroom room ,如果我想使用上面提到的新功能,这样做会导致实例化Mazeroom room Also IMazeRooms cannot be modified. IMazeRooms 也不能修改。

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.我可能只是将另一个接口与我想要包含的功能一起使用,这将由 IMazeroom 实现,但这似乎很奇怪,因为这个约束应该在这里教我一些东西,而我看不到仅使用另一个接口的价值。 Furthermore, using another interface would not really cut down on code duplication, I am looking for something more like a abstract class此外,使用另一个接口并不能真正减少代码重复,我正在寻找更像抽象 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.编辑:由于我们无法更改界面,您可以使用实现 IMazeRoom 的DefaultRoom class。

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:由于您必须通过IMazeRoom myIMazeRoomObject = new DefaultRoom()来实例化它,只要您知道您正在处理哪种房间,您就可以简单地将其转换回:

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() .旁注:需要注意的重要一点是,该接口仅实现必要的方法getAdjacentRoom ,因此它仅构成依赖于getAdjacentRooms()的某些(任意)布局的信息。 Your secondary constraints (immutable interface + instantiation) make it necessary to circumvent something that shouldn't happen with proper OO architecture.您的次要约束(不可变接口 + 实例化)使得有必要规避正确的 OO 架构不应该发生的事情。

You can seperate the common concrete implemetation into a abstact class and keep the interface.您可以将常见的具体实现分离为抽象的 class 并保留接口。

Rough example based on "I am not allowed to change the interface though":基于“我不允许更改界面”的粗略示例:

IMazeRoom: 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. ... 与额外房间的 TreasureRoom 相同。

Comment: Now all rooms are treated as IMazeRoom...评论:现在所有房间都被视为 IMazeRoom...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM