创建Java子类的层次结构
我试图在java中建立一个位置层次结构。一个地方可以大也可以小,较大的地方包括较小的子位置。所以,一个世界包含国家,国家包含城市,等等,直到建筑物和房间 我创建了一个名为Place的抽象类,它是所有这些类型的父类。每个位置都包含子位置图、父位置图和获取父位置(也称为邻居)的能力 我遇到的主要问题是,父类的子位置应该是类的实例,但是没有办法用java来指定这一点 我考虑过对所有类型进行硬编码,这样City的getParent会返回一个国家,getSublocations会返回一个建筑图,但这会在更改类的功能或添加新类时产生一些问题,并且会涉及大量的代码复制。还有其他办法解决这个问题吗 编辑: 谢谢你的回答。这就是我目前所拥有的。这并不完美,但也不太糟糕。我必须复制的唯一代码是getNeights()的实现。它过去直接在抽象类(this.getParent().getSublocations().getEdges(this))中实现,但这只是一行代码创建Java子类的层次结构,java,abstract,Java,Abstract,我试图在java中建立一个位置层次结构。一个地方可以大也可以小,较大的地方包括较小的子位置。所以,一个世界包含国家,国家包含城市,等等,直到建筑物和房间 我创建了一个名为Place的抽象类,它是所有这些类型的父类。每个位置都包含子位置图、父位置图和获取父位置(也称为邻居)的能力 我遇到的主要问题是,父类的子位置应该是类的实例,但是没有办法用java来指定这一点 我考虑过对所有类型进行硬编码,这样City的getParent会返回一个国家,getSublocations会返回一个建筑图,但这会在更
import java.util.HashSet;
public abstract class Place {
//World, Region, City, Building, Room
public enum Direction {
East, Northeast, North, Northwest, West, Southwest, South, Southeast, Invalid;
public static Direction fromInt(int i) {
switch (i) {
case 0: return East;
case 1: return Northeast;
case 2: return North;
case 3: return Northwest;
case 4: return West;
case 5: return Southwest;
case 6: return South;
case 7: return Southeast;
default: return Invalid;
}
}
public static Direction fromAngle(double angle) {
return fromInt((int) (angle+22.5)/45);
}
}
protected final int locked = Integer.MAX_VALUE;
protected int x, y; //longitude and latitude
public abstract String getName();
public abstract <S extends Place> Graph<S> getSublocations();
public abstract <T extends Place> T getParent();
public abstract <U extends Place> HashSet<Passage<U>> getNeighbors();
public final Direction getDirection(Place otherPlace) {
if (otherPlace == null) {
return Direction.Invalid;
} else if (this.getClass() == otherPlace.getClass()) {
return Direction.fromAngle(Math.atan2(otherPlace.y-y, otherPlace.x-x));
} else {
return Direction.Invalid;
}
}
}
import java.util.HashSet;
公共抽象类场所{
//世界、地区、城市、建筑物、房间
公共枚举方向{
东、东北、北、西北、西、西南、南、东南、无效;
从int(int i)开始的公共静态方向{
开关(一){
案例0:返回东部;
案例1:返回东北;
案例2:返回北方;
案例3:返回西北;
案例4:返回西部;
案例5:返回西南;
案例6:返回南方;
案例7:返回东南部;
默认:返回无效;
}
}
公共静态方向从角度(双角度){
从int((int)(角度+22.5)/45)返回;
}
}
受保护的最终整数锁定=整数最大值;
受保护的整数x,y;//经度和纬度
公共抽象字符串getName();
公共抽象图getSublocations();
公共摘要T getParent();
公共抽象HashSet getneights();
公共最终方向getDirection(地点其他地点){
if(otherPlace==null){
返回方向无效;
}else if(this.getClass()==otherPlace.getClass()){
返回方向。从角度(数学atan2(otherPlace.y-y,otherPlace.x-x));
}否则{
返回方向无效;
}
}
}
我有过几次这样的问题,当你遇到类似的问题时,我不建议在这种情况下使用泛型,因为你已经知道每个地方将返回什么。希望这段代码能有所帮助
public interface Place {
// Place can be an abstract class if you want.
// Making it abstract could cause some problems because it might make you use generics
// I recommend an interface
List<? extends Place> getSublocations();
Place getParent();
}
public class World implements Place {
private List<Country> countries;
@Override
public List<Country> getSublocations() {
return this.countries;
}
@Override
public Place getParent() {
return null;
}
}
public class Country implements Place {
private List<City> cities;
private World parent;
@Override
public List<City> getSublocations() {
return this.cities;
}
@Override
public World getParent() {
return this.parent;
}
}
public class City implements Place {
private Country parent;
@Override
public List<? extends Place> getSublocations() {
return null;
}
@Override
public Country getParent() {
return this.parent;
}
}
公共接口场所{
//如果需要,Place可以是一个抽象类。
//将其抽象可能会导致一些问题,因为它可能会使您使用泛型
//我推荐一个接口
列表假设每种类型都直接从位置扩展(而不是像城市扩展国家,这是错误的),您应该能够用泛型限制您的样板文件,例如:
public class Place<P extends Place<?, ?>, C extends Place<?, ?>> {
// ...
public final P getParent() { ... }
public final Set<C> getChildren() { ... }
}
public class City extends Place<Country, Building> { ... )
public class Place>{
// ...
公共最终P getParent(){…}
公共最终集getChildren(){…}
}
公共类城市扩展位置{…)
然而,在实践中,您可能会发现在这两种情况下更灵活的做法是简单地返回位置
,并避免在类型系统中硬编码层次结构不同级别之间的关系。如果情况发生变化(例如,在国家
和城市
之间引入州
类型)您必须根据之前的关系更正每个呼叫站点。查看组合模式,并可能使用一些标记接口。国家/地区是否可以包含非城市位置?即,您是否尝试根据类型筛选兄弟位置,或者您是否尝试在添加时将可能的类型限制在某个级别?是否可以你放了一些代码摘录?这可能有助于我们了解你在寻找什么注意,在现实世界中,这些关系中的许多都不是严格的等级关系。有一些城市在技术上不在任何国家或跨越多个州/国家,仅举一个例子。对于简单的任务,显然等级关系就足够了,但just fair警告它可能会反过来咬你:)听起来你在尝试使用继承(IS-A),而你应该使用组合(HAS-A).World有国家对象,但国家不是世界。国家有城市,但城市不是国家。@azurefrog每层场所只能包含较低层的场所。因此,城市只包含建筑。主要需要的功能是,当getParent()、getSublocations()时,任何场所都会返回指定类型的场所,并调用getNeights()。