访问package-private子类的实例作为其公共超类

时间:2015-12-21 16:40:57

标签: java inheritance subclass private superclass

我正在编写一个多人游戏引擎,我将传统的MVC模式映射到游戏/客户端/服务器(游戏是其他部分作用并通过其进行通信的“模型”。客户端内部有自己的MVC结构。)

我正在尽力确保客户端和服务器软件包永远不会跨越路径,除非通过常见的抽象进行通信。同样,Game模型永远不会依赖于来自客户端或服务器的类。

但是我遇到了一个问题:

  • 服务器显然知道客户不需要的大量信息。例如,虽然客户需要了解其他连接的Player对象(使用“nickname”和“ping”等信息),但他们当然不需要知道其他玩家的IP地址,连接时间,帐户信息,等
  • 这导致我编写了代表相同信息的特定于包的类。例如,我在Game模型中为所有连接的用户都有一个Player对象,但是有一个相应的User对象可以在Server包中存储其他信息。两个包中都有一个HashMap,用于存储相应的对象,并使用相同的ID绑定。
  • (在我的项目中有一堆相同模式的实例。一些信息位于Game模型中,而在Server模型中有一个相应的对象,其中包含服务器需要的其他信息。)
  • 这不太理想,因为我现在需要确保更改(例如播放器断开连接)反映在多个区域。

所以理想的解决方案(特别是播放器/用户问题)将是这样的:

  • Game包中有一个Player类,只有Game和Client需要的字段和方法。
  • 在Server包中有一个名为User strong privately 的子类。该类具有连接和身份验证的方法和字段。
  • Game模型中有一个HashMap,用于存储由(int)ID映射的玩家。
  • 如果应用程序作为监听或专用服务器运行,此HashMap实际上将填充用户对象

我的问题是,游戏和客户端包可以将这些对象作为公共超类(Player)访问,即使实际上它是属于另一个包的子类的实例吗?来自游戏和客户的观点一样,他们只需要访问超类方法/字段。

(另外,显然,如果应用程序作为客户端运行,服务器将仅发送信息以生成Player对象。用户将仅存储在专用/侦听实例上。)

我测试了这个但是我的游戏远没有编译(目前正在进行重构噩梦,需要清理新手错误)并且我不确定IDE是否会检测到任何运行时冲突。

1 个答案:

答案 0 :(得分:0)

我同意你可以在一个新项目中快速充实这一点,但我很好奇它究竟会如何运作,所以无论如何我都这样做了:

玩家类:

package sandbox.pakcage1;

public class Player {
    public Player(String name) {
        this.name = name;
    }

    private String name;

    public String getName() {
        return name;
    }
}

用户类:

package sandbox.package2;

import sandbox.pakcage1.Player;

class User extends Player {
    private String userID;

    public User(String name, String id) {
        super(name);
        this.userID = id;
    }

    public String getUserID() {
        return userID;
    }
}

生成一些用户的类:

package sandbox.package2;

import java.util.ArrayList;
import java.util.List;
import sandbox.pakcage1.Player;

public class UserBuilder {
    public static List<Player> getUsers() {
        List<Player> users = new ArrayList<>();

        users.add(new User("Joe", "1"));
        users.add(new User("Bob", "2"));

        return users;
    }
}

将所有这些联系在一起的主要内容:

package sandbox;

import java.util.List;
import sandbox.package2.UserBuilder;
import sandbox.pakcage1.Player;

public class Sandbox {
    public static void main(String[] args) {
        List<Player> players = UserBuilder.getUsers();

        for(Player player : players) {
            System.out.println(player.getName());
        }
    }
}

你会发现主要功能完美,从User对象访问Player数据成员就好了。您不能将它们转换为User对象,或者以任何方式访问User数据 - 因为该类在不同的包中受到包保护。