![](/img/trans.png)
[英]Java Reflections getSubTypeOf not returning all subclasses of the Hierarchy
[英]Creating a hierarchy of Java subclasses
我正在嘗試在java中設置位置的層次結構。 一個地方可以大也可以小,更大的地方包括較小的子位置。 因此,世界包含國家,國家包含城市,依此類推,直到建築物和房間。
我創建了一個名為Place的抽象類,它是所有這些類型的父類。 每個地方都包含一個子位置圖,一個父位置以及獲取父子位置(也就是一個鄰居)的功能。
我遇到的主要問題是,父母的子位置應該是某人的類的實例,但是無法用java來指定。
我已經考慮過對所有類型進行硬編碼,因此City的getParent返回一個Country,而getSublocations返回一個Building Graph,但是這在更改類的功能或添加新類方面造成了一些問題,並且涉及大量的代碼復制。 還有其他解決方法嗎?
編輯:
感謝所有的答案。 到目前為止,這就是我所擁有的。 這不是完美的,但也不錯。 我唯一要復制的代碼是getNeighbors()的實現。 它曾經直接在抽象類(this.getParent()。getSublocations()。getEdges(this))中實現,但這只是一行代碼。
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;
}
}
}
我已經遇到過幾次這個問題,當您遇到類似這樣的問題時,我不建議您在這種情況下使用泛型,因為您已經知道每個地方將要返回的內容。 希望這段代碼會有所幫助。
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
擴展(與City extends Country
,這是錯誤的),那么您應該能夠使用泛型來限制樣板,例如:
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> { ... )
但是,實際上,您可能會發現,在兩種情況下都簡單地返回Place
,並且避免在類型系統中硬編碼層次結構的不同級別之間的關系,會更靈活。 如果事情發生了變化(例如,您在“ Country
和“ City
之間引入了State
類型),則必須更正依賴於先前關系的每個呼叫站點。
看一下復合圖案,也許使用一些標記界面。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.