[英]Class implementing interface should be able to only add an object of the same class
[英]Detecting Class of an object implementing an interface
我正在编写一个游戏,作为该游戏玩家的一部分,他们应该能够单击各种GUI项目,并在GUI的特定区域查看更多详细信息。 我正在通过接口Detailable
来实现此目的,该接口由适当的游戏对象实现,并将适当的信息发送到JPanel
还有一些容器(所有这些容器都实现Detailable
),其中包含其他对象( Detailable
实现)。 目标是可以单击一个容器,并在其统计信息中查看其内容,然后可以依次单击其内容以查看其统计信息,等等。
我遇到的问题是在编写容器的addToContents(Detailable d)
方法。 每个容器都为容器“类型”的ArrayList<String>
-衣柜,书柜等。我希望能够仅将某些类添加到给定容器-因此具有“书柜”类型的容器将只接受例如Book
或Curio
类的对象。
我目前拥有的是:
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;
}
}
但这感觉是错误的方法。 有没有更好的办法? 理想情况下,出于简单代码的考虑,我会有类似(伪代码)的信息
Constructor:
private ArrayList<Class> classesAccepted = <list of classes>
addToContents:
if (classesAccepted.contains(d.getClass()){
add the thingie to contents
return true
}
else{
return 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);
}
实际上,您可以使用Map
,如下所示:
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
}
如果我正确理解了您的问题,那么您正在寻找这样的东西
ArrayList <Class<? extends Detailable>> acceptedClasses = new ArrayList<>();
acceptedClasses.add(Bookcase.class);
acceptedClasses.add(OtherAcceptable.class);
然后做一些类似于
boolean test =
acceptedClasses.stream().anyMatch(clazz -> aClass.isInstance(detailableInstance));
检查实例是否为可接受的类型
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.