我有:
我想做什么:
检查列表中的当前元素是CD还是Book,如果是,则将其名称设置为字段fldName中的字符串。
问题:
final ObservableList<Object extends Media> medium = FXCollections.observableArrayList(
它说,
代码:
final TableView<Object> mediaTable = new TableView<>();
final ObservableList<Object extends Media> medium = FXCollections.observableArrayList(
new Book(),
new CD(),
new Book(),
new CD(),
new Book()
);
/*Lots of other stuff in between here*/
/*The first if-statememen checks if any field(fldName) is empty*/
else if(medium.get(mediaTable.getSelectionModel().getSelectedIndex()).getClass()
.getSimpleName() == "CD" ||
medium.get(mediaTable.getSelectionModel().getSelectedIndex())
.getClass().getSimpleName() == "Book"){
String strName = mediaTable.getSelectionModel().getSelectedIndex()).getName();
if(!fldName.getText().isEmpty()){
strName = fldName.getText();
}
}
/*Lots of other stuff below here*/
这个在某种程度上有所帮助,但不是一个完整的解决方案: Calling member-function of generic member
我认为这个可能有一些解决方案,但我不明白: Java - Generic List of Generic Abstract Classes
那么我该如何解决这个问题?
编辑: Media,Book&amp; amp; CD,
public abstract class Media<T>{
private String author;
private String name;
private String genre;
private String publisher;
private String mediaType;
private double price;
private int year;
private T length;
//*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*//
public String getAuthor(){
return author;
}
public String getName(){
return name;
}
public String getGenre(){
return genre;
}
public String getPublisher(){
return publisher;
}
public String getMediaType(){
return mediaType;
}
public double getPrice(){
return price;
}
public int getYear(){
return year;
}
public T getLength(){
return length;
}
//*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*//
public void setAuthor(String author){
this.author = author;
}
public void setName(String name){
this.name = name;
}
public void setGenre(String genre){
this.genre = genre;
}
public void setPublisher(String publisher){
this.publisher = publisher;
}
public void setMediaType(String mediaType){
this.mediaType = mediaType;
}
public void setPrice(double price){
this.price = price;
}
public void setYear(int year){
this.year = year;
}
public void setLength(T length){
this.length = length;
}
public Media(String name, String author, String genre, String publisher, String mediaType, double price, int year){
setName(name);
setAuthor(author);
setGenre(genre);
setPublisher(publisher);
setMediaType(mediaType);
setPrice(price);
setYear(year);
}
}
public class Book extends Media<Integer>{
private String coverType;
public String getCoverType(){
return coverType;
}
public void setCoverType(String coverType){
this.coverType = coverType;
}
public Book(String name, String author, String genre, String publisher, String mediaType, double price,
int year, int length, String coverType){
super(name, author, genre, publisher, mediaType, price, year);
setLength(length);
setCoverType(coverType);
}
public Book(){
super("N/A", "N/A", "N/A", "N/A", "N/A", 0.0, 0);
setLength(0);
setCoverType("N/A");
}
}
public class CD extends Media<Double>{
private String type;
public String getCdType(){
return type;
}
public void setCdType(String type){
this.type = type;
}
public CD(String name, String author, String genre, String publisher, String mediaType, double price,
int year, double length, String type){
super(name, author, genre, publisher, mediaType, price, year);
setLength(length);
setCdType(type);
}
public CD(){
super("N/A", "N/A", "N/A", "N/A", "N/A", 0.0, 0);
setLength(0.0);
setCdType("N/A");
}
}
编辑2: 在TableView和ObservableList中从“Object extends Media”更改为“Media”,现在出现了这些错误:
代码:
final TableView<Media> mediaTable = new TableView<>();
final ObservableList<Media> medium = FXCollections.observableArrayList(
new Book(),
new CD(),
new Book(),
new CD(),
new Book()
);
编辑3:
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
final TableView<Media<T>> mediaTable = new TableView<>();
final ObservableList<Media<T>> medium = FXCollections.observableArrayList(
new Book(),
new CD(),
new Book(),
new CD(),
new Book()
);
答案 0 :(得分:3)
ObservableList<Object extends Media>
是语法错误的原因是类型参数边界仅在定义类或方法而非变量时适用。
更准确地说 - 您可以在类型参数上设置边界,而不是在类型本身上设置边界:class MyClass<T extends OtherClass> {}
没问题,因为您在类型参数 T
上应用了边界。
定义变量时,您必须具有特定类型,因此在您的情况下,您将拥有ObservableList<Media>
,因为您知道列表中的所有项目都是Media
个实例(无论它们是Book
} s或CD
s)。
请注意,在泛型类或方法的范围内,类型参数本身是绑定的,因此您可以使用以下内容:
class MyClass<T extends OtherClass> {
// When instantiating a MyClass object, T will be bound, and while you don't know the exact type
// you can be certain it will be `OtherClass`, or some class that extends it.
private List<T> myList;
}
总而言之,您的TableView
和ObservableList
都应该有Media
作为类型参数,因为这是您愿意接受的最常规类型。
至于检查列表中每个项目的实际类型,正如@RC所说instanceof
比比较类名更好(更安全,也可能更快)选项:
// Since we declared mediaTable as TableView<Media>, getSelectedItem() returns a Media object, which will either be a Book or a CD
Media currentMedia = mediaTable.getSelectionModel().getSelectedItem();
if (currentMedia instanceof Book) {
// safe cast because we know currentMedia is indeed an instance of Book
Book currentBook = (Book)currentMedia;
...
} else if (currentMedia instanceof CD) {
CD currentCD = (CD)currentMedia;
}
答案 1 :(得分:0)
将类型参数更改为像@sillyfly这样的媒体说是正确的,但你也必须转换里面的项目。
所以如果以前的版本看起来像这样:
final TableView<Media> mediaTable = new TableView<>();
final ObservableList<Media> medium = FXCollections.observableArrayList(
new Book(),
new CD(),
new Book(),
new CD(),
new Book()
);
功能正常的版本如下所示:
final TableView<Media<?>> mediaTable = new TableView<>();
final ObservableList<Media<?>> medium = FXCollections.observableArrayList(
(Media<?>)new Book(),
(Media<?>)new CD(),
(Media<?>)new Book(),
(Media<?>)new CD(),
(Media<?>)new Book()
);
并且,如果类型参数为Media
,则必须将书籍(例如)设为(Media)new Book()