Java 检测实现接口的对象的类
我正在编写一个游戏,作为这个游戏的一部分,玩家应该能够点击各种GUI项目,并查看GUI特定区域的更多详细信息。我通过一个接口来管理这个问题,这个接口是由合适的游戏对象实现的,并将适当的信息发送到Java 检测实现接口的对象的类,java,class,implements,Java,Class,Implements,我正在编写一个游戏,作为这个游戏的一部分,玩家应该能够点击各种GUI项目,并查看GUI特定区域的更多详细信息。我通过一个接口来管理这个问题,这个接口是由合适的游戏对象实现的,并将适当的信息发送到JPanel 还有包含其他(Detailable实现)对象的容器(所有容器都实现了Detailable)。目标是可以点击一个容器,在它的统计数据中,看到它的内容,然后依次点击它来查看它们的统计数据,等等 我遇到的问题是编写容器的addToContents(Detailable d)方法。每个容器作为容器“
JPanel
还有包含其他(Detailable
实现)对象的容器(所有容器都实现了Detailable
)。目标是可以点击一个容器,在它的统计数据中,看到它的内容,然后依次点击它来查看它们的统计数据,等等
我遇到的问题是编写容器的addToContents(Detailable d)
方法。每个容器作为容器“类型”的ArrayList
——衣柜、书架等。我希望能够仅向给定容器添加某些类——因此,具有“bookcase”类型的容器将仅接受类Book
或古玩
的对象
我目前拥有的是:
public boolean addToContents(Detailable d){
if(this.types.contains("bookcase") && d.getClass().getName().equals("Book")){
//do some stuff
//I know "Book" isn't the right syntax, this is just to demo
return true;
}
else if(this.types.contains("bookcase") && d.getClass().getName().equals("Curio")){
//other stuff
return true;
}
//etc
else{
return false;
}
}
但这感觉是错误的做法。有更好的办法吗?理想情况下,为了便于编写代码,我会使用类似(伪代码)的代码
构造函数:
私有ArrayList类已接受=
添加内容:
if(classesAccepted.contains(d.getClass()){
将内容添加到内容中
返回真值
}
否则{
返回false;
}
但我似乎找不到向构造函数添加类列表的方法——将类名的ArrayList转换为对实际类的引用的ArrayList
容器当前从JSON读取,因此包含两个类:
public class FurnitureType {
private String name;
private List<String> type;
private int cost;
private String description;
private int comfortBonus;
private int capacity;
//plus getters for all the above
}
public class Furniture implements Detailable, ListSelectionListener{
private String name;
private List<String> types;
private int cost;
private String description;
private int comfortBonus;
private int capacity;
private ArrayList<Detailable> contents;
private transient DetailPanel dp = null;
public Furniture (FurnitureType type){
this.name=type.getName();
this.types = type.getType();
this.cost = type.getCost();
this.description = type.getDescription();
this.comfortBonus = type.getComfortBonus();
this.capacity = type.getCapacity();
this.contents = new ArrayList();
}
//appropriate getters
public boolean addToContents(Detailable d){
if(this.types.contains("bookcase") && d.getClass().getName().equals("Book")){
//do some stuff
//I know "Book" isn't the right syntax, this is just to demo
return true;
}
else if(this.types.contains("bookcase") && d.getClass().getName().equals("Curio")){
//other stuff
return true;
}
//etc
else{
return false;
}
}
@Override
public String toString(){
return description;
}
@Override
public Icon getBigPic() {
return null;
}
@Override
public JComponent getStats() {
Object [] objectContents = contents.toArray();
JList contentList = new JList(objectContents);
contentList.setPreferredSize(new Dimension (400, 300));
contentList.setFixedCellHeight(50);
contentList.addListSelectionListener(this);
contentList.setCellRenderer(new CustomCellRenderer());
//the CustomCellRenderer class simply makes long descriptions into multiline cells
return contentList;
}
@Override
public void addPanel(DetailPanel dp) {
this.dp = dp;
}
@Override
public void valueChanged(ListSelectionEvent lse) {
Detailable d = contents.get(lse.getFirstIndex());
dp.updatePanel(d);
}
公共类家具类型{
私有字符串名称;
私有列表类型;
私人成本;
私有字符串描述;
私人红利;
私人int能力;
//加上以上所有的getters
}
公共类家具实现了详细的ListSelectionListener{
私有字符串名称;
私有列表类型;
私人成本;
私有字符串描述;
私人红利;
私人int能力;
私有数组列表内容;
专用面板dp=null;
公共家具(家具类){
this.name=type.getName();
this.types=type.getType();
this.cost=type.getCost();
this.description=type.getDescription();
this.comfortBonus=type.getComfortBonus();
this.capacity=type.getCapacity();
this.contents=new ArrayList();
}
//适当的吸气剂
公共布尔添加内容(可详细说明的d){
if(this.types.contains(“书架”)和&d.getClass().getName().equals(“书本”)){
//做点什么
//我知道“Book”不是正确的语法,这只是为了演示
返回true;
}
else if(this.types.contains(“书架”)和&d.getClass().getName().equals(“古董”)){
//其他东西
返回true;
}
//等
否则{
返回false;
}
}
@凌驾
公共字符串toString(){
返回说明;
}
@凌驾
公共图标getBigPic(){
返回null;
}
@凌驾
公共JComponent getStats(){
Object[]objectContents=contents.toArray();
JList contentList=新的JList(objectContents);
setPreferredSize(新维度(400300));
contentList.setFixedCellHeight(50);
contentList.addListSelectionListener(此);
setCellRenderer(新的CustomCellRenderer());
//CustomCellRenderer类只是将长描述放入多行单元格中
返回内容列表;
}
@凌驾
公共无效添加面板(详细面板dp){
这是dp=dp;
}
@凌驾
公共作废值已更改(ListSelectionEvent lse){
Detailable d=contents.get(lse.getFirstIndex());
dp.updatePanel(d);
}
如果我正确理解了您的问题,您正在寻找类似的问题
ArrayList <Class<? extends Detailable>> acceptedClasses = new ArrayList<>();
acceptedClasses.add(Bookcase.class);
acceptedClasses.add(OtherAcceptable.class);
要检查实例是否属于可接受的类型,您可以实际使用
映射
,如下所示:
private static Map<String, List<Class<? extends Detailable>>>
bookcaseContainer = new HashMap<>();
static {
//load the bookcaseContainer Map from properties/database
bookcaseContainer.put("bookcase", list1);
bookcaseContainer.put("wardrobe", list2);
}
if(bookcaseContainer.get("bookcase") != null &&
bookcaseContainer.get("bookcase").contains(d.getClass())) {
//do something here
} else if(bookcaseContainer.get("wardrobe") != null &&
bookcaseContainer.get("wardrobe").contains(d.getClass())) {
//do something here
}
private static map你的伪代码就快到了,对吗?问题出在哪里?抱歉,为了清楚起见,我会更新这个问题-你是对的,我没有特别说明这个问题。这本书和《古玩》有一个共同的超类型?它们没有,但如果这是一个更简单的解决方案,它们可能有。目前它们都没有扩展任何东西,你能吗告诉我们您当前容器的外观如何?简单地new ArrayList()
在Java 7+Federico中应该很好,我真的应该先通过编译器运行它。感谢您指出这一点,修复了类与clazz的打字错误,并处理了布尔问题。干杯:)回答很好,谢谢你的帮助。接受了另一个,因为代码稍微短了一点,我不能接受两个,但这是一个很好的解决方案。
boolean test =
acceptedClasses.stream().anyMatch(clazz -> aClass.isInstance(detailableInstance));
private static Map<String, List<Class<? extends Detailable>>>
bookcaseContainer = new HashMap<>();
static {
//load the bookcaseContainer Map from properties/database
bookcaseContainer.put("bookcase", list1);
bookcaseContainer.put("wardrobe", list2);
}
if(bookcaseContainer.get("bookcase") != null &&
bookcaseContainer.get("bookcase").contains(d.getClass())) {
//do something here
} else if(bookcaseContainer.get("wardrobe") != null &&
bookcaseContainer.get("wardrobe").contains(d.getClass())) {
//do something here
}