[英]List of generic object s extending abstract class
我有 :
我想做什么 :
检查列表中的当前元素是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*/
这在一定程度上有所帮助,但不是完整的解决方案: 调用泛型成员的member-function
我认为这可能有一些解决方案,但我不明白: Java-通用抽象类的通用列表
那么我该如何解决呢?
编辑:媒体,书籍和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中从“对象扩展媒体”更改为“媒体”,现在出现以下错误:
代码 :
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()
);
ObservableList<Object extends Media>
是语法错误的原因是,类型参数范围仅适用于定义类或方法,而不适用于变量。
更精确地讲-您可以在类型参数上设置边界,而不是在类型本身上设置边界: class MyClass<T extends OtherClass> {}
可以,因为您将边界应用于类型参数 T
定义变量时,您必须具有特定的类型,因此在您的情况下,您将具有ObservableList<Media>
,因为您知道列表中的所有项目都是Media
实例(无论是Book
还是CD
)。
请注意,在泛型类或方法的范围内,类型参数本身是绑定的,因此您可以进行如下操作:
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
, 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;
}
像@sillyfly所说的那样将type参数更改为Media是正确的,但是您还必须在其中转换项目。
因此,如果以前的版本如下所示:
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
,然后将Book(例如)制作为(Media)new Book()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.