访问包私有子类的实例作为其 public 超类
Accessing instance of a package-private subclass as its public superclass
我正在编写一个多人游戏引擎,我将传统的 MVC 模式映射到 Game/Client/Server(游戏是其他部分作用和通信的 "model"。客户端有它的内部拥有 MVC 结构。)
我正在尽最大努力确保客户端和服务器包永远不会交叉,除非通过公共抽象进行通信。同样,游戏模型从不依赖于来自客户端或服务器的 classes。
但是我运行遇到了一个问题:
- 服务器显然知道大量客户不需要的信息。例如,虽然客户端需要知道其他也已连接的 Player 对象(具有 "nickname" 和 "ping" 等信息),但他们当然不需要知道其他 Player 的 IP 地址、连接时间、账户信息等
- 这导致我编写了代表相同信息的包特定 classes。例如,我在 Game 模型中为所有连接的用户提供了一个 Player 对象,但是在 Server 包中有一个相应的 User 对象存储附加信息。两个包中都有一个HashMap,存储对应的对象,绑定相同的ID。
- (我的项目中有很多相同模式的实例。一些信息位于游戏模型中,而在服务器模型中有一个对应的对象,其中包含服务器需要的附加信息。 )
- 这不太理想,因为我现在需要确保更改(例如玩家断开连接)反映在多个区域。
所以理想的解决方案(特别是 Player/User 问题)应该是这样的:
- Game 包中有一个 Player class,它只有 Game 和 Client 需要的字段和方法。
- 在服务器包中有一个名为 User 的子class 私下 声明。此 class 具有用于连接和身份验证的方法和字段。
- Game 模型中有一个存储 Players 的 HashMap,由 (int) ID 映射。
- 如果应用程序 运行 作为侦听或专用服务器,此 HashMap 实际上会填充用户对象。
那么,我的问题是 Game 和 Client 包能否将这些对象作为 public superclass(Player)访问,即使实际上它是subclass属于另一个包? 从Game和Client的角度来看,他们只需要访问superclass methods/fields.
(此外,很明显,如果应用程序 运行 作为客户端,服务器将仅向其发送信息以创建 Player 对象。用户将仅存储在 dedicated/listen 实例上。)
我会对此进行测试,但我的游戏还远未通过编译(目前正在经历一场重构噩梦,需要清理新手错误)而且我不确定 IDE 是否会检测到任何运行时间冲突。
我同意你可以在一个新项目中非常快速地充实它,但我很好奇它究竟会如何运作,所以我还是做了:
一名玩家class:
package sandbox.pakcage1;
public class Player {
public Player(String name) {
this.name = name;
}
private String name;
public String getName() {
return name;
}
}
一个用户class:
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;
}
}
一个class生成一些用户:
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());
}
}
}
您会发现 main 功能完美,从 User 对象访问 Player 数据成员就很好。但是,您不能将它们转换为用户对象,也不能以任何方式访问用户数据 - 因为 class 在不同的包中受到包保护。
我正在编写一个多人游戏引擎,我将传统的 MVC 模式映射到 Game/Client/Server(游戏是其他部分作用和通信的 "model"。客户端有它的内部拥有 MVC 结构。)
我正在尽最大努力确保客户端和服务器包永远不会交叉,除非通过公共抽象进行通信。同样,游戏模型从不依赖于来自客户端或服务器的 classes。
但是我运行遇到了一个问题:
- 服务器显然知道大量客户不需要的信息。例如,虽然客户端需要知道其他也已连接的 Player 对象(具有 "nickname" 和 "ping" 等信息),但他们当然不需要知道其他 Player 的 IP 地址、连接时间、账户信息等
- 这导致我编写了代表相同信息的包特定 classes。例如,我在 Game 模型中为所有连接的用户提供了一个 Player 对象,但是在 Server 包中有一个相应的 User 对象存储附加信息。两个包中都有一个HashMap,存储对应的对象,绑定相同的ID。
- (我的项目中有很多相同模式的实例。一些信息位于游戏模型中,而在服务器模型中有一个对应的对象,其中包含服务器需要的附加信息。 )
- 这不太理想,因为我现在需要确保更改(例如玩家断开连接)反映在多个区域。
所以理想的解决方案(特别是 Player/User 问题)应该是这样的:
- Game 包中有一个 Player class,它只有 Game 和 Client 需要的字段和方法。
- 在服务器包中有一个名为 User 的子class 私下 声明。此 class 具有用于连接和身份验证的方法和字段。
- Game 模型中有一个存储 Players 的 HashMap,由 (int) ID 映射。
- 如果应用程序 运行 作为侦听或专用服务器,此 HashMap 实际上会填充用户对象。
那么,我的问题是 Game 和 Client 包能否将这些对象作为 public superclass(Player)访问,即使实际上它是subclass属于另一个包? 从Game和Client的角度来看,他们只需要访问superclass methods/fields.
(此外,很明显,如果应用程序 运行 作为客户端,服务器将仅向其发送信息以创建 Player 对象。用户将仅存储在 dedicated/listen 实例上。)
我会对此进行测试,但我的游戏还远未通过编译(目前正在经历一场重构噩梦,需要清理新手错误)而且我不确定 IDE 是否会检测到任何运行时间冲突。
我同意你可以在一个新项目中非常快速地充实它,但我很好奇它究竟会如何运作,所以我还是做了:
一名玩家class:
package sandbox.pakcage1;
public class Player {
public Player(String name) {
this.name = name;
}
private String name;
public String getName() {
return name;
}
}
一个用户class:
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;
}
}
一个class生成一些用户:
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());
}
}
}
您会发现 main 功能完美,从 User 对象访问 Player 数据成员就很好。但是,您不能将它们转换为用户对象,也不能以任何方式访问用户数据 - 因为 class 在不同的包中受到包保护。